PikaCV_Filter.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include "PikaCV_Filter.h"
  2. #include "PikaCV_Converter.h"
  3. #include "PikaCV_common.h"
  4. #include "dataQueue.h"
  5. void PikaCV_Filter_meanFilter(PikaObj* self,
  6. PikaObj* image,
  7. int ksizex,
  8. int ksizey) {
  9. PikaCV_Image* src = obj_getStruct(image, "image");
  10. int width = src->width;
  11. int height = src->height;
  12. if (NULL == src) {
  13. pika_assert(0);
  14. return;
  15. }
  16. if (ksizex % 2 == 0 || ksizey % 2 == 0) {
  17. pika_assert(0);
  18. return;
  19. }
  20. if (src->format == PikaCV_ImageFormat_Type_GRAY) {
  21. int hh = (ksizey - 1) / 2;
  22. int hw = (ksizex - 1) / 2;
  23. int sum = 0;
  24. int mean = 0;
  25. int area = ksizex * ksizey;
  26. int width_new = width - ksizex + 1;
  27. int height_new = height - ksizey + 1;
  28. int size_new = width_new * height_new;
  29. Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
  30. uint8_t* data = _image_getData(image);
  31. uint8_t* data_new = arg_getBytes(arg_data_new);
  32. for (int i = hh; i < height_new + hh; ++i) {
  33. for (int j = hw; j < width_new + hw; ++j) {
  34. for (int r = i - hh; r <= i + hh; ++r) {
  35. for (int c = j - hw; c <= j + hw; ++c) {
  36. // sum = Newsrc.at<uchar>(r, c) + sum;
  37. sum += data[r * width + c];
  38. }
  39. }
  40. // mean = sum / (wsize.area());
  41. // dst.at<uchar>(i-hh,j-hw)=mean;
  42. mean = sum / area;
  43. data_new[(i - hh) * width_new + (j - hw)] = mean;
  44. sum = 0;
  45. mean = 0;
  46. }
  47. }
  48. src->height = height_new;
  49. src->width = width_new;
  50. src->size = size_new;
  51. obj_setBytes(image, "_data", data_new, size_new);
  52. arg_deinit(arg_data_new);
  53. return;
  54. } else if (src->format != PikaCV_ImageFormat_Type_RGB888) {
  55. PikaCV_Converter_toRGB888(self, image);
  56. }
  57. int hh = (ksizey - 1) / 2;
  58. int hw = (ksizex - 1) / 2;
  59. int sumr = 0, sumg = 0, sumb = 0;
  60. int meanr = 0, meang = 0, meanb = 0;
  61. int area = ksizex * ksizey;
  62. int width_new = width - ksizex + 1;
  63. int height_new = height - ksizey + 1;
  64. int size_new = width_new * height_new * 3;
  65. Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
  66. uint8_t* data = _image_getData(image);
  67. uint8_t* data_new = arg_getBytes(arg_data_new);
  68. for (int i = hh; i < height_new + hh; ++i) {
  69. for (int j = hw; j < width_new + hw; ++j) {
  70. for (int r = i - hh; r <= i + hh; ++r) {
  71. for (int c = j - hw; c <= j + hw; ++c) {
  72. sumr += data[r * width * 3 + c * 3];
  73. sumg += data[r * width * 3 + c * 3 + 1];
  74. sumb += data[r * width * 3 + c * 3 + 2];
  75. }
  76. }
  77. meanr = sumr / area;
  78. meang = sumg / area;
  79. meanb = sumb / area;
  80. data_new[(i - hh) * width_new * 3 + (j - hw) * 3] = meanr;
  81. data_new[(i - hh) * width_new * 3 + (j - hw) * 3 + 1] = meang;
  82. data_new[(i - hh) * width_new * 3 + (j - hw) * 3 + 2] = meanb;
  83. sumr = 0;
  84. sumg = 0;
  85. sumb = 0;
  86. meanb = 0;
  87. meang = 0;
  88. meanr = 0;
  89. }
  90. }
  91. src->height = height_new;
  92. src->width = width_new;
  93. src->size = size_new;
  94. obj_setBytes(image, "_data", data_new, size_new);
  95. arg_deinit(arg_data_new);
  96. return;
  97. }
  98. typedef struct _Range {
  99. uint8_t start, end;
  100. } Range;
  101. Range new_Range(uint8_t s, uint8_t e) {
  102. Range r;
  103. r.start = s;
  104. r.end = e;
  105. return r;
  106. }
  107. void swap(uint8_t* x, uint8_t* y) {
  108. uint8_t t = *x;
  109. *x = *y;
  110. *y = t;
  111. }
  112. void quick_sort(uint8_t arr[], const int len) {
  113. Range* r;
  114. int p = 0;
  115. if (len <= 0) {
  116. return;
  117. }
  118. r = (Range*)pikaMalloc(sizeof(Range) * len);
  119. if (r == NULL) {
  120. return;
  121. }
  122. r[p++] = new_Range(0, len - 1);
  123. while (p) {
  124. Range range = r[--p];
  125. if (range.start >= range.end)
  126. continue;
  127. int mid = arr[(range.start + range.end) / 2];
  128. int left = range.start, right = range.end;
  129. do {
  130. while (arr[left] < mid)
  131. ++left;
  132. while (arr[right] > mid)
  133. --right;
  134. if (left <= right) {
  135. swap(&arr[left], &arr[right]);
  136. left++;
  137. right--;
  138. }
  139. } while (left <= right);
  140. if (range.start < right)
  141. r[p++] = new_Range(range.start, right);
  142. if (range.end > left)
  143. r[p++] = new_Range(left, range.end);
  144. }
  145. pikaFree((void*)r, sizeof(Range) * len);
  146. }
  147. void PikaCV_Filter_medianFilter(PikaObj* self, PikaObj* image) {
  148. PikaCV_Image* src = obj_getStruct(image, "image");
  149. int width = src->width;
  150. int height = src->height;
  151. int ksizex = 3;
  152. int ksizey = 3;
  153. if (NULL == src) {
  154. pika_assert(0);
  155. return;
  156. }
  157. if (src->format == PikaCV_ImageFormat_Type_GRAY) {
  158. int hh = (ksizey - 1) / 2;
  159. int hw = (ksizex - 1) / 2;
  160. int width_new = width - ksizex + 1;
  161. int height_new = height - ksizey + 1;
  162. const int size_new = width_new * height_new;
  163. uint8_t data_tmp[9] = {0};
  164. Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
  165. uint8_t* data = _image_getData(image);
  166. uint8_t* data_new = arg_getBytes(arg_data_new);
  167. for (int i = hh; i < height_new + hh; ++i) {
  168. for (int j = hw; j < width_new + hw; ++j) {
  169. int index = 0;
  170. for (int r = i - hh; r <= i + hh; ++r) {
  171. for (int c = j - hw; c <= j + hw; ++c) {
  172. data_tmp[index++] = data[r * width + c];
  173. }
  174. }
  175. quick_sort(data_tmp, 9);
  176. data_new[(i - hh) * width_new + (j - hw)] = data_tmp[4];
  177. }
  178. }
  179. src->height = height_new;
  180. src->width = width_new;
  181. src->size = size_new;
  182. obj_setBytes(image, "_data", data_new, size_new);
  183. arg_deinit(arg_data_new);
  184. return;
  185. } else if (src->format != PikaCV_ImageFormat_Type_RGB888) {
  186. PikaCV_Converter_toRGB888(self, image);
  187. }
  188. int hh = (ksizey - 1) / 2;
  189. int hw = (ksizex - 1) / 2;
  190. int width_new = width - ksizex + 1;
  191. int height_new = height - ksizey + 1;
  192. const int size_new = width_new * height_new * 3;
  193. uint8_t data_tmpr[9] = {0};
  194. uint8_t data_tmpg[9] = {0};
  195. uint8_t data_tmpb[9] = {0};
  196. Arg* arg_data_new = arg_setBytes(NULL, "", NULL, size_new);
  197. uint8_t* data = _image_getData(image);
  198. uint8_t* data_new = arg_getBytes(arg_data_new);
  199. for (int i = hh; i < height_new + hh; ++i) {
  200. for (int j = hw; j < width_new + hw; ++j) {
  201. int index = 0;
  202. for (int r = i - hh; r <= i + hh; ++r) {
  203. for (int c = j - hw; c <= j + hw; ++c) {
  204. data_tmpr[index] = data[r * width * 3 + c * 3];
  205. data_tmpg[index] = data[r * width * 3 + c * 3 + 1];
  206. data_tmpb[index] = data[r * width * 3 + c * 3 + 2];
  207. index++;
  208. }
  209. }
  210. quick_sort(data_tmpr, 9);
  211. quick_sort(data_tmpg, 9);
  212. quick_sort(data_tmpb, 9);
  213. data_new[(i - hh) * width_new * 3 + (j - hw) * 3] = data_tmpr[4];
  214. data_new[(i - hh) * width_new * 3 + (j - hw) * 3 + 1] =
  215. data_tmpg[4];
  216. data_new[(i - hh) * width_new * 3 + (j - hw) * 3 + 2] =
  217. data_tmpb[4];
  218. }
  219. }
  220. src->height = height_new;
  221. src->width = width_new;
  222. src->size = size_new;
  223. obj_setBytes(image, "_data", data_new, size_new);
  224. arg_deinit(arg_data_new);
  225. return;
  226. }