detect_main.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #include "find_ellipse.h"
  2. #include "track_ellipse.h"
  3. // Global variables used by OpenCL functions
  4. cl_context context;
  5. cl_command_queue command_queue;
  6. cl_device_id device;
  7. int main(int argc, char ** argv) {
  8. // Make sure the command line arguments have been specified
  9. if (argc !=3) {
  10. fprintf(stderr, "Usage: %s <input file> <number of frames to process>", argv[0]);
  11. exit(EXIT_FAILURE);
  12. }
  13. // Choose the best GPU in case there are multiple available
  14. choose_GPU();
  15. // Keep track of the start time of the program
  16. long long program_start_time = get_time();
  17. // Let the user specify the number of frames to process
  18. int num_frames = atoi(argv[2]);
  19. // Open video file
  20. char *video_file_name = argv[1];
  21. avi_t *cell_file = AVI_open_input_file(video_file_name, 1);
  22. if (cell_file == NULL) {
  23. AVI_print_error("Error with AVI_open_input_file");
  24. exit(EXIT_FAILURE);
  25. }
  26. // Transfer precomputed constants to the GPU
  27. compute_constants();
  28. int i, j, *crow, *ccol, pair_counter = 0, x_result_len = 0, Iter = 20, ns = 4, k_count = 0, n;
  29. MAT *cellx, *celly, *A;
  30. double *GICOV_spots, *t, *G, *x_result, *y_result, *V, *QAX_CENTERS, *QAY_CENTERS;
  31. double threshold = 1.8, radius = 10.0, delta = 3.0, dt = 0.01, b = 5.0;
  32. // Extract a cropped version of the first frame from the video file
  33. MAT *image_chopped = get_frame(cell_file, 0, 1, 0);
  34. printf("Detecting cells in frame 0\n");
  35. // Get gradient matrices in x and y directions
  36. MAT *grad_x = gradient_x(image_chopped);
  37. MAT *grad_y = gradient_y(image_chopped);
  38. m_free(image_chopped);
  39. // Get GICOV matrices corresponding to image gradients
  40. long long GICOV_start_time = get_time();
  41. MAT *gicov = GICOV(grad_x, grad_y);
  42. long long GICOV_end_time = get_time();
  43. // Dilate the GICOV matrices
  44. long long dilate_start_time = get_time();
  45. MAT *img_dilated = dilate(gicov);
  46. long long dilate_end_time = get_time();
  47. // Find possible matches for cell centers based on GICOV and record the rows/columns in which they are found
  48. pair_counter = 0;
  49. crow = (int *) malloc(gicov->m * gicov->n * sizeof(int));
  50. ccol = (int *) malloc(gicov->m * gicov->n * sizeof(int));
  51. for(i = 0; i < gicov->m; i++) {
  52. for(j = 0; j < gicov->n; j++) {
  53. 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)))
  54. {
  55. crow[pair_counter]=i;
  56. ccol[pair_counter]=j;
  57. pair_counter++;
  58. }
  59. }
  60. }
  61. GICOV_spots = (double *) malloc(sizeof(double) * pair_counter);
  62. for(i = 0; i < pair_counter; i++)
  63. GICOV_spots[i] = sqrt(m_get_val(gicov, crow[i], ccol[i]));
  64. G = (double *) calloc(pair_counter, sizeof(double));
  65. x_result = (double *) calloc(pair_counter, sizeof(double));
  66. y_result = (double *) calloc(pair_counter, sizeof(double));
  67. x_result_len = 0;
  68. for (i = 0; i < pair_counter; i++) {
  69. if ((crow[i] > 29) && (crow[i] < BOTTOM - TOP + 39)) {
  70. x_result[x_result_len] = ccol[i];
  71. y_result[x_result_len] = crow[i] - 40;
  72. G[x_result_len] = GICOV_spots[i];
  73. x_result_len++;
  74. }
  75. }
  76. // Make an array t which holds each "time step" for the possible cells
  77. t = (double *) malloc(sizeof(double) * 36);
  78. for (i = 0; i < 36; i++) {
  79. t[i] = (double)i * 2.0 * PI / 36.0;
  80. }
  81. // Store cell boundaries (as simple circles) for all cells
  82. cellx = m_get(x_result_len, 36);
  83. celly = m_get(x_result_len, 36);
  84. for(i = 0; i < x_result_len; i++) {
  85. for(j = 0; j < 36; j++) {
  86. m_set_val(cellx, i, j, x_result[i] + radius * cos(t[j]));
  87. m_set_val(celly, i, j, y_result[i] + radius * sin(t[j]));
  88. }
  89. }
  90. A = TMatrix(9,4);
  91. V = (double *) malloc(sizeof(double) * pair_counter);
  92. QAX_CENTERS = (double * )malloc(sizeof(double) * pair_counter);
  93. QAY_CENTERS = (double *) malloc(sizeof(double) * pair_counter);
  94. memset(V, 0, sizeof(double) * pair_counter);
  95. memset(QAX_CENTERS, 0, sizeof(double) * pair_counter);
  96. memset(QAY_CENTERS, 0, sizeof(double) * pair_counter);
  97. // For all possible results, find the ones that are feasibly leukocytes and store their centers
  98. k_count = 0;
  99. for (n = 0; n < x_result_len; n++) {
  100. if ((G[n] < -1 * threshold) || G[n] > threshold) {
  101. MAT * x, *y;
  102. VEC * x_row, * y_row;
  103. x = m_get(1, 36);
  104. y = m_get(1, 36);
  105. x_row = v_get(36);
  106. y_row = v_get(36);
  107. // Get current values of possible cells from cellx/celly matrices
  108. x_row = get_row(cellx, n, x_row);
  109. y_row = get_row(celly, n, y_row);
  110. uniformseg(x_row, y_row, x, y);
  111. // Make sure that the possible leukocytes are not too close to the edge of the frame
  112. if ((m_min(x) > b) && (m_min(y) > b) && (m_max(x) < cell_file->width - b) && (m_max(y) < cell_file->height - b)) {
  113. MAT * Cx, * Cy, *Cy_temp, * Ix1, * Iy1;
  114. VEC *Xs, *Ys, *W, *Nx, *Ny, *X, *Y;
  115. Cx = m_get(1, 36);
  116. Cy = m_get(1, 36);
  117. Cx = mmtr_mlt(A, x, Cx);
  118. Cy = mmtr_mlt(A, y, Cy);
  119. Cy_temp = m_get(Cy->m, Cy->n);
  120. for (i = 0; i < 9; i++)
  121. m_set_val(Cy, i, 0, m_get_val(Cy, i, 0) + 40.0);
  122. // Iteratively refine the snake/spline
  123. for (i = 0; i < Iter; i++) {
  124. int typeofcell;
  125. if(G[n] > 0.0) typeofcell = 0;
  126. else typeofcell = 1;
  127. splineenergyform01(Cx, Cy, grad_x, grad_y, ns, delta, 2.0 * dt, typeofcell);
  128. }
  129. X = getsampling(Cx, ns);
  130. for (i = 0; i < Cy->m; i++)
  131. m_set_val(Cy_temp, i, 0, m_get_val(Cy, i, 0) - 40.0);
  132. Y = getsampling(Cy_temp, ns);
  133. Ix1 = linear_interp2(grad_x, X, Y);
  134. Iy1 = linear_interp2(grad_x, X, Y);
  135. Xs = getfdriv(Cx, ns);
  136. Ys = getfdriv(Cy, ns);
  137. Nx = v_get(Ys->dim);
  138. for (i = 0; i < Ys->dim; i++)
  139. 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)));
  140. Ny = v_get(Xs->dim);
  141. for (i = 0; i < Xs->dim; i++)
  142. 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)));
  143. W = v_get(Nx->dim);
  144. for (i = 0; i < Nx->dim; i++)
  145. 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));
  146. V[n] = mean(W) / std_dev(W);
  147. // Find the cell centers by computing the means of X and Y values for all snaxels of the spline contour
  148. QAX_CENTERS[k_count] = mean(X);
  149. QAY_CENTERS[k_count] = mean(Y) + TOP;
  150. k_count++;
  151. // Free memory
  152. v_free(W);
  153. v_free(Ny);
  154. v_free(Nx);
  155. v_free(Ys);
  156. v_free(Xs);
  157. m_free(Iy1);
  158. m_free(Ix1);
  159. v_free(Y);
  160. v_free(X);
  161. m_free(Cy_temp);
  162. m_free(Cy);
  163. m_free(Cx);
  164. }
  165. // Free memory
  166. v_free(y_row);
  167. v_free(x_row);
  168. m_free(y);
  169. m_free(x);
  170. }
  171. }
  172. // Free memory
  173. free(V);
  174. free(ccol);
  175. free(crow);
  176. free(GICOV_spots);
  177. free(t);
  178. free(G);
  179. free(x_result);
  180. free(y_result);
  181. m_free(A);
  182. m_free(celly);
  183. m_free(cellx);
  184. m_free(img_dilated);
  185. m_free(gicov);
  186. m_free(grad_y);
  187. m_free(grad_x);
  188. // Report the total number of cells detected
  189. printf("Cells detected: %d\n\n", k_count);
  190. // Report the breakdown of the detection runtime
  191. printf("Detection runtime\n");
  192. printf("-----------------\n");
  193. printf("GICOV computation: %.5f seconds\n", ((float) (GICOV_end_time - GICOV_start_time)) / (1000*1000));
  194. printf(" GICOV dilation: %.5f seconds\n", ((float) (dilate_end_time - dilate_start_time)) / (1000*1000));
  195. printf(" Total: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
  196. // Now that the cells have been detected in the first frame,
  197. // track the ellipses through subsequent frames
  198. if (num_frames > 1) printf("\nTracking cells across %d frames\n", num_frames);
  199. else printf("\nTracking cells across 1 frame\n");
  200. long long tracking_start_time = get_time();
  201. int num_snaxels = 20;
  202. ellipsetrack(cell_file, QAX_CENTERS, QAY_CENTERS, k_count, radius, num_snaxels, num_frames);
  203. printf(" Total: %.5f seconds\n", ((float) (get_time() - tracking_start_time)) / (float) (1000*1000*num_frames));
  204. // Report total program execution time
  205. printf("\nTotal application run time: %.5f seconds\n", ((float) (get_time() - program_start_time)) / (1000*1000));
  206. return 0;
  207. }