lamino-roi.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <math.h>
  2. #include <glib.h>
  3. #include "lamino-roi.h"
  4. static inline void
  5. swap (gint *first, gint *second) {
  6. gint tmp;
  7. tmp = *first;
  8. *first = *second;
  9. *second = tmp;
  10. }
  11. /**
  12. * Determine the left and right column to read from a projection at a given
  13. * tomographic angle.
  14. */
  15. void
  16. determine_x_extrema (gfloat extrema[2], GValueArray *x_extrema, GValueArray *y_extrema,
  17. gfloat tomo_angle, gfloat x_center)
  18. {
  19. gfloat sin_tomo, cos_tomo;
  20. gint x_min, x_max, y_min, y_max;
  21. sin_tomo = sin (tomo_angle);
  22. cos_tomo = cos (tomo_angle);
  23. x_min = EXTRACT_INT (x_extrema, 0);
  24. /* The interval is right-opened when OpenCL indices for both x and y are generated, */
  25. /* so the last index doesn't count */
  26. x_max = EXTRACT_INT (x_extrema, 1) - 1;
  27. y_min = EXTRACT_INT (y_extrema, 0);
  28. y_max = EXTRACT_INT (y_extrema, 1) - 1;
  29. if (sin_tomo < 0) {
  30. swap (&y_min, &y_max);
  31. }
  32. if (cos_tomo < 0) {
  33. swap (&x_min, &x_max);
  34. }
  35. /* -1 to make sure the interpolation doesn't reach to uninitialized values*/
  36. extrema[0] = cos_tomo * x_min + sin_tomo * y_min + x_center - 1;
  37. /* +1 because extrema[1] will be accessed by interpolation
  38. * but the region in copying is right-open */
  39. extrema[1] = cos_tomo * x_max + sin_tomo * y_max + x_center + 1;
  40. }
  41. /**
  42. * Determine the top and bottom row to read from a projection at given
  43. * tomographic and laminographic angles.
  44. */
  45. void
  46. determine_y_extrema (gfloat extrema[2], GValueArray *x_extrema, GValueArray *y_extrema,
  47. gfloat z_extrema[2], gfloat tomo_angle, gfloat lamino_angle,
  48. gfloat y_center)
  49. {
  50. gfloat sin_tomo, cos_tomo, sin_lamino, cos_lamino;
  51. gint x_min, x_max, y_min, y_max;
  52. sin_tomo = sin (tomo_angle);
  53. cos_tomo = cos (tomo_angle);
  54. sin_lamino = sin (lamino_angle);
  55. cos_lamino = cos (lamino_angle);
  56. x_min = EXTRACT_INT (x_extrema, 0);
  57. x_max = EXTRACT_INT (x_extrema, 1) - 1;
  58. y_min = EXTRACT_INT (y_extrema, 0);
  59. y_max = EXTRACT_INT (y_extrema, 1) - 1;
  60. if (sin_tomo < 0) {
  61. swap (&x_min, &x_max);
  62. }
  63. if (cos_tomo > 0) {
  64. swap (&y_min, &y_max);
  65. }
  66. extrema[0] = sin_tomo * x_min - cos_tomo * y_min;
  67. extrema[1] = sin_tomo * x_max - cos_tomo * y_max;
  68. extrema[0] = extrema[0] * cos_lamino + z_extrema[0] * sin_lamino + y_center - 1;
  69. extrema[1] = extrema[1] * cos_lamino + z_extrema[1] * sin_lamino + y_center + 1;
  70. }
  71. /**
  72. * clip:
  73. * @result: resulting clipped extrema
  74. * @extrema: (min, max)
  75. * @maximum: projection width or height
  76. *
  77. * Clip extrema to an allowed interval [0, projection width/height)
  78. */
  79. void
  80. clip (gint result[2], gfloat extrema[2], gint maximum)
  81. {
  82. result[0] = (gint) floorf (extrema[0]);
  83. result[1] = (gint) ceilf (extrema[1]);
  84. if (result[0] < 0) {
  85. result[0] = 0;
  86. }
  87. if (result[0] > maximum) {
  88. result[0] = maximum;
  89. }
  90. if (result[1] < 0) {
  91. result[1] = 0;
  92. }
  93. if (result[1] > maximum) {
  94. result[1] = maximum;
  95. }
  96. if (result[0] == result[1]) {
  97. if (result[1] < maximum) {
  98. result[1]++;
  99. } else if (result[0] > 0) {
  100. result[0]--;
  101. } else {
  102. g_warning ("Cannot extend");
  103. }
  104. } else if (result[0] > result[1]) {
  105. g_warning ("Invalid extrema: minimum larger than maximum");
  106. }
  107. }
  108. /**
  109. * Determine the left and right column to read from a projection at a given
  110. * tomographic angle. The result is bound to [0, projection width)
  111. */
  112. void
  113. determine_x_region (gint result[2], GValueArray *x_extrema, GValueArray *y_extrema, gfloat tomo_angle,
  114. gfloat x_center, gint width)
  115. {
  116. gfloat extrema[2];
  117. determine_x_extrema (extrema, x_extrema, y_extrema, tomo_angle, x_center);
  118. clip (result, extrema, width);
  119. }
  120. /**
  121. * Determine the top and bottom column to read from a projection at given
  122. * tomographic and laminographic angles. The result is bound to
  123. * [0, projection height).
  124. */
  125. void
  126. determine_y_region (gint result[2], GValueArray *x_extrema, GValueArray *y_extrema, gfloat z_extrema[2],
  127. gfloat tomo_angle, gfloat lamino_angle, gfloat y_center, gint height)
  128. {
  129. gfloat extrema[2];
  130. determine_y_extrema (extrema, x_extrema, y_extrema, z_extrema, tomo_angle,
  131. lamino_angle, y_center);
  132. clip (result, extrema, height);
  133. }