123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- #include "find_ellipse.h"
- #include "track_ellipse.h"
- // Global variables used by OpenCL functions
- cl_context context;
- cl_command_queue command_queue;
- cl_device_id device;
- // Helper function to print usage
- void usage(char *argv0) {
- char *help =
- "\nUsage: %s [switches] \n\n"
- " -i :input file \n"
- " -f :frames to process \n"
- " -p platform_id :OCL platform to use [default=0]\n"
- " -d device_id :OCL device to use [default=0]\n"
- " -g use_gpu :1 for GPU 0 for CPU [default=0]\n";
- fprintf(stderr, help, argv0);
- exit(-1);
- }
- int main(int argc, char ** argv) {
-
- // Let the user specify the number of frames to process
- int num_frames = 0;
-
- // Open video file
- char *video_file_name = 0;
-
- // Arguments parsing for platform, device and type
- // Variables to store information on platform and device to use_gpu
- int platform_id = 0;
- int device_id = 0;
- int use_gpu = 0;
- /* obtain command line arguments and change appropriate options */
- int opt;
- extern char *optarg;
- while ((opt=getopt(argc,argv,"i:f:p:d:g:"))!= EOF) {
- switch (opt) {
- case 'p': platform_id = atoi(optarg);
- break;
- case 'd': device_id = atoi(optarg);
- break;
- case 'g': use_gpu = atoi(optarg);
- break;
- case 'i': video_file_name = optarg;
- break;
- case 'f': num_frames = atoi(optarg);
- break;
- case '?': usage(argv[0]);
- break;
- default: usage(argv[0]);
- break;
- }
- }
- // Choose the best GPU in case there are multiple available
- choose_GPU(platform_id, device_id, use_gpu);
- // Keep track of the start time of the program
- long long program_start_time = get_time();
-
- avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
- if (cell_file == NULL) {
- AVI_print_error("Error with AVI_open_input_file");
- exit(EXIT_FAILURE);
- }
-
- // Transfer precomputed constants to the GPU
- compute_constants();
-
- int i, j, *crow, *ccol, pair_counter = 0, x_result_len = 0, Iter = 20, ns = 4, k_count = 0, n;
- MAT *cellx, *celly, *A;
- double *GICOV_spots, *t, *G, *x_result, *y_result, *V, *QAX_CENTERS, *QAY_CENTERS;
- double threshold = 1.8, radius = 10.0, delta = 3.0, dt = 0.01, b = 5.0;
-
- // Extract a cropped version of the first frame from the video file
- MAT *image_chopped = get_frame(cell_file, 0, 1, 0);
- printf("Detecting cells in frame 0\n");
-
- // Get gradient matrices in x and y directions
- MAT *grad_x = gradient_x(image_chopped);
- MAT *grad_y = gradient_y(image_chopped);
-
- m_free(image_chopped);
-
- // Get GICOV matrices corresponding to image gradients
- long long GICOV_start_time = get_time();
- MAT *gicov = GICOV(grad_x, grad_y);
- long long GICOV_end_time = get_time();
-
- // Dilate the GICOV matrices
- long long dilate_start_time = get_time();
- MAT *img_dilated = dilate(gicov);
- long long dilate_end_time = get_time();
-
- // Find possible matches for cell centers based on GICOV and record the rows/columns in which they are found
- pair_counter = 0;
- crow = (int *) malloc(gicov->m * gicov->n * sizeof(int));
- ccol = (int *) malloc(gicov->m * gicov->n * sizeof(int));
- for(i = 0; i < gicov->m; i++) {
- for(j = 0; j < gicov->n; j++) {
- if(!double_eq(m_get_val(gicov,i,j), 0.0) && double_eq(m_get_val(img_dilated,i,j), m_get_val(gicov,i,j)))
- {
- crow[pair_counter]=i;
- ccol[pair_counter]=j;
- pair_counter++;
- }
- }
- }
- GICOV_spots = (double *) malloc(sizeof(double) * pair_counter);
- for(i = 0; i < pair_counter; i++)
- GICOV_spots[i] = sqrt(m_get_val(gicov, crow[i], ccol[i]));
-
- G = (double *) calloc(pair_counter, sizeof(double));
- x_result = (double *) calloc(pair_counter, sizeof(double));
- y_result = (double *) calloc(pair_counter, sizeof(double));
-
- x_result_len = 0;
- for (i = 0; i < pair_counter; i++) {
- if ((crow[i] > 29) && (crow[i] < BOTTOM - TOP + 39)) {
- x_result[x_result_len] = ccol[i];
- y_result[x_result_len] = crow[i] - 40;
- G[x_result_len] = GICOV_spots[i];
- x_result_len++;
- }
- }
-
- // Make an array t which holds each "time step" for the possible cells
- t = (double *) malloc(sizeof(double) * 36);
- for (i = 0; i < 36; i++) {
- t[i] = (double)i * 2.0 * PI / 36.0;
- }
-
- // Store cell boundaries (as simple circles) for all cells
- cellx = m_get(x_result_len, 36);
- celly = m_get(x_result_len, 36);
- for(i = 0; i < x_result_len; i++) {
- for(j = 0; j < 36; j++) {
- m_set_val(cellx, i, j, x_result[i] + radius * cos(t[j]));
- m_set_val(celly, i, j, y_result[i] + radius * sin(t[j]));
- }
- }
-
- A = TMatrix(9,4);
- V = (double *) malloc(sizeof(double) * pair_counter);
- QAX_CENTERS = (double * )malloc(sizeof(double) * pair_counter);
- QAY_CENTERS = (double *) malloc(sizeof(double) * pair_counter);
- memset(V, 0, sizeof(double) * pair_counter);
- memset(QAX_CENTERS, 0, sizeof(double) * pair_counter);
- memset(QAY_CENTERS, 0, sizeof(double) * pair_counter);
- // For all possible results, find the ones that are feasibly leukocytes and store their centers
- k_count = 0;
- for (n = 0; n < x_result_len; n++) {
- if ((G[n] < -1 * threshold) || G[n] > threshold) {
- MAT * x, *y;
- VEC * x_row, * y_row;
- x = m_get(1, 36);
- y = m_get(1, 36);
- x_row = v_get(36);
- y_row = v_get(36);
- // Get current values of possible cells from cellx/celly matrices
- x_row = get_row(cellx, n, x_row);
- y_row = get_row(celly, n, y_row);
- uniformseg(x_row, y_row, x, y);
- // Make sure that the possible leukocytes are not too close to the edge of the frame
- if ((m_min(x) > b) && (m_min(y) > b) && (m_max(x) < cell_file->width - b) && (m_max(y) < cell_file->height - b)) {
- MAT * Cx, * Cy, *Cy_temp, * Ix1, * Iy1;
- VEC *Xs, *Ys, *W, *Nx, *Ny, *X, *Y;
- Cx = m_get(1, 36);
- Cy = m_get(1, 36);
- Cx = mmtr_mlt(A, x, Cx);
- Cy = mmtr_mlt(A, y, Cy);
-
- Cy_temp = m_get(Cy->m, Cy->n);
-
- for (i = 0; i < 9; i++)
- m_set_val(Cy, i, 0, m_get_val(Cy, i, 0) + 40.0);
-
- // Iteratively refine the snake/spline
- for (i = 0; i < Iter; i++) {
- int typeofcell;
-
- if(G[n] > 0.0) typeofcell = 0;
- else typeofcell = 1;
-
- splineenergyform01(Cx, Cy, grad_x, grad_y, ns, delta, 2.0 * dt, typeofcell);
- }
-
- X = getsampling(Cx, ns);
- for (i = 0; i < Cy->m; i++)
- m_set_val(Cy_temp, i, 0, m_get_val(Cy, i, 0) - 40.0);
- Y = getsampling(Cy_temp, ns);
-
- Ix1 = linear_interp2(grad_x, X, Y);
- Iy1 = linear_interp2(grad_x, X, Y);
- Xs = getfdriv(Cx, ns);
- Ys = getfdriv(Cy, ns);
-
- Nx = v_get(Ys->dim);
- for (i = 0; i < Ys->dim; i++)
- v_set_val(Nx, i, v_get_val(Ys, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
-
- Ny = v_get(Xs->dim);
- for (i = 0; i < Xs->dim; i++)
- v_set_val(Ny, i, -1.0 * v_get_val(Xs, i) / sqrt(v_get_val(Xs, i)*v_get_val(Xs, i) + v_get_val(Ys, i)*v_get_val(Ys, i)));
-
- W = v_get(Nx->dim);
- for (i = 0; i < Nx->dim; i++)
- v_set_val(W, i, m_get_val(Ix1, 0, i) * v_get_val(Nx, i) + m_get_val(Iy1, 0, i) * v_get_val(Ny, i));
-
- V[n] = mean(W) / std_dev(W);
-
- // Find the cell centers by computing the means of X and Y values for all snaxels of the spline contour
- QAX_CENTERS[k_count] = mean(X);
- QAY_CENTERS[k_count] = mean(Y) + TOP;
-
- k_count++;
-
- // Free memory
- v_free(W);
- v_free(Ny);
- v_free(Nx);
- v_free(Ys);
- v_free(Xs);
- m_free(Iy1);
- m_free(Ix1);
- v_free(Y);
- v_free(X);
- m_free(Cy_temp);
- m_free(Cy);
- m_free(Cx);
- }
- // Free memory
- v_free(y_row);
- v_free(x_row);
- m_free(y);
- m_free(x);
- }
- }
-
- // Free memory
- free(V);
- free(ccol);
- free(crow);
- free(GICOV_spots);
- free(t);
- free(G);
- free(x_result);
- free(y_result);
- m_free(A);
- m_free(celly);
- m_free(cellx);
- m_free(img_dilated);
- m_free(gicov);
- m_free(grad_y);
- m_free(grad_x);
-
- // Report the total number of cells detected
- printf("Cells detected: %d\n\n", k_count);
-
- // Report the breakdown of the detection runtime
- printf("Detection runtime\n");
- printf("-----------------\n");
- printf("GICOV computation: %.5f seconds\n", ((float) (GICOV_end_time - GICOV_start_time)) / (1000*1000));
- printf(" GICOV dilation: %.5f seconds\n", ((float) (dilate_end_time - dilate_start_time)) / (1000*1000));
- printf(" Total: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
-
- // Now that the cells have been detected in the first frame,
- // track the ellipses through subsequent frames
- if (num_frames > 1) printf("\nTracking cells across %d frames\n", num_frames);
- else printf("\nTracking cells across 1 frame\n");
- long long tracking_start_time = get_time();
- int num_snaxels = 20;
- ellipsetrack(cell_file, QAX_CENTERS, QAY_CENTERS, k_count, radius, num_snaxels, num_frames);
- printf(" Total: %.5f seconds\n", ((float) (get_time() - tracking_start_time)) / (float) (1000*1000*num_frames));
-
- // Report total program execution time
- printf("\nTotal application run time: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
- return 0;
- }
|