find_ellipse_kernel.cl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // The number of sample points in each ellipse (stencil)
  2. #define NPOINTS 150
  3. // The maximum radius of a sample ellipse
  4. #define MAX_RAD 20
  5. // The total number of sample ellipses
  6. #define NCIRCLES 7
  7. // The size of the structuring element used in dilation
  8. #define STREL_SIZE (12 * 2 + 1)
  9. // Kernel to find the maximal GICOV value at each pixel of a
  10. // video frame, based on the input x- and y-gradient matrices
  11. #ifdef USE_IMAGE
  12. __kernel void GICOV_kernel(int grad_m, image2d_t grad_x, image2d_t grad_y, __constant float *c_sin_angle,
  13. __constant float *c_cos_angle, __constant int *c_tX, __constant int *c_tY, __global float *gicov) {
  14. #else
  15. __kernel void GICOV_kernel(int grad_m, __global float *grad_x, __global float *grad_y, __constant float *c_sin_angle,
  16. __constant float *c_cos_angle, __constant int *c_tX, __constant int *c_tY, __global float *gicov, int width, int height) {
  17. #endif
  18. int i, j, k, n, x, y;
  19. int gid = get_global_id(0);
  20. if(gid>=width*height)
  21. return;
  22. // Determine this thread's pixel
  23. i = gid/width + MAX_RAD + 2;
  24. j = gid%width + MAX_RAD + 2;
  25. // Initialize the maximal GICOV score to 0
  26. float max_GICOV = 0.f;
  27. #ifdef USE_IMAGE
  28. // Define the sampler for accessing the images
  29. const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
  30. #endif
  31. // Iterate across each stencil
  32. for (k = 0; k < NCIRCLES; k++) {
  33. // Variables used to compute the mean and variance
  34. // of the gradients along the current stencil
  35. float sum = 0.f, M2 = 0.f, mean = 0.f;
  36. // Iterate across each sample point in the current stencil
  37. for (n = 0; n < NPOINTS; n++) {
  38. // Determine the x- and y-coordinates of the current sample point
  39. y = j + c_tY[(k * NPOINTS) + n];
  40. x = i + c_tX[(k * NPOINTS) + n];
  41. // Compute the combined gradient value at the current sample point
  42. #ifdef USE_IMAGE
  43. int2 addr = {y, x};
  44. float p = read_imagef(grad_x, sampler, addr).x * c_cos_angle[n] +
  45. read_imagef(grad_y, sampler, addr).x * c_sin_angle[n];
  46. #else
  47. int addr = x * grad_m + y;
  48. float p = grad_x[addr] * c_cos_angle[n] + grad_y[addr] * c_sin_angle[n];
  49. #endif
  50. // Update the running total
  51. sum += p;
  52. // Partially compute the variance
  53. float delta = p - mean;
  54. mean = mean + (delta / (float) (n + 1));
  55. M2 = M2 + (delta * (p - mean));
  56. }
  57. // Finish computing the mean
  58. mean = sum / ((float) NPOINTS);
  59. // Finish computing the variance
  60. float var = M2 / ((float) (NPOINTS - 1));
  61. // Keep track of the maximal GICOV value seen so far
  62. if (((mean * mean) / var) > max_GICOV) max_GICOV = (mean * mean) / var;
  63. }
  64. // Store the maximal GICOV value
  65. gicov[(i * grad_m) + j] = max_GICOV;
  66. }
  67. // Kernel to compute the dilation of the GICOV matrix produced by the GICOV kernel
  68. // Each element (i, j) of the output matrix is set equal to the maximal value in
  69. // the neighborhood surrounding element (i, j) in the input matrix
  70. // Here the neighborhood is defined by the structuring element (c_strel)
  71. #ifdef USE_IMAGE
  72. __kernel void dilate_kernel(int img_m, int img_n, int strel_m, int strel_n, __constant float *c_strel,
  73. image2d_t img, __global float *dilated) {
  74. #else
  75. __kernel void dilate_kernel(int img_m, int img_n, int strel_m, int strel_n, __constant float *c_strel,
  76. __global float *img, __global float *dilated) {
  77. #endif
  78. // Find the center of the structuring element
  79. int el_center_i = strel_m / 2;
  80. int el_center_j = strel_n / 2;
  81. // Determine this thread's location in the matrix
  82. int thread_id = get_global_id(0); //(blockIdx.x * blockDim.x) + threadIdx.x;
  83. int i = thread_id % img_m;
  84. int j = thread_id / img_m;
  85. if(j > img_n) return;
  86. // Initialize the maximum GICOV score seen so far to zero
  87. float max = 0.0f;
  88. #ifdef USE_IMAGE
  89. // Define the sampler for accessing the image
  90. const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST;
  91. #endif
  92. // Iterate across the structuring element in one dimension
  93. int el_i, el_j, x, y;
  94. // Lingjie Zhang modificated at 11/06/2015
  95. if (j < img_n){
  96. for (el_i = 0; el_i < strel_m; el_i++) {
  97. y = i - el_center_i + el_i;
  98. // Make sure we have not gone off the edge of the matrix
  99. if ( (y >= 0) && (y < img_m) ) {
  100. // Iterate across the structuring element in the other dimension
  101. for (el_j = 0; el_j < strel_n; el_j++) {
  102. x = j - el_center_j + el_j;
  103. // Make sure we have not gone off the edge of the matrix
  104. // and that the current structuring element value is not zero
  105. if ( (x >= 0) &&
  106. (x < img_n) &&
  107. (c_strel[(el_i * strel_n) + el_j] != 0) ) {
  108. // Determine if this is the maximal value seen so far
  109. #ifdef USE_IMAGE
  110. int2 addr = {y, x};
  111. float temp = read_imagef(img, sampler, addr).x;
  112. #else
  113. int addr = (x * img_m) + y;
  114. float temp = img[addr];
  115. #endif
  116. if (temp > max) max = temp;
  117. }
  118. }
  119. }
  120. }
  121. // Store the maximum value found
  122. dilated[(i * img_n) + j] = max;
  123. }
  124. // end of Lingjie Zhang's modification
  125. }