Advertisement
Guest User

filter.c

a guest
Dec 15th, 2019
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.31 KB | None | 0 0
  1. #include "Filter.h"
  2. #include <math.h>
  3.  
  4. #define ABS(x) ((x>0)? x : -x)
  5.  
  6. typedef union {
  7. uint8_t pix[4];
  8. unsigned full;
  9. } OneToFourPixels;
  10.  
  11. float BOX_BLUR_KERNEL_3[9] = { 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
  12. 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
  13. 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0
  14. };
  15.  
  16. float BOX_BLUR_KERNEL_5[25] = { 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0,
  17. 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0,
  18. 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0,
  19. 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0,
  20. 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0, 1.0 / 25.0,
  21. };
  22.  
  23. float GAUSSIAN_BLUR_KERNEL[49] = {
  24. 0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067,
  25. 0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292,
  26. 0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117,
  27. 0.00038771, 0.01330373, 0.11098164, 0.22508352, 0.11098164, 0.01330373, 0.00038771,
  28. 0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117,
  29. 0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292,
  30. 0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067
  31. };
  32.  
  33. int SOBEL_KERNEL_X[9] = { -1.0, 0.0, 1.0,
  34. -2.0, 0.0, 2.0,
  35. -1.0, 0.0, 1.0,
  36. };
  37.  
  38. int SOBEL_KERNEL_Y[9] = { -1.0, -2.0, -1.0,
  39. 0.0, 0.0, 0.0,
  40. 1.0, 2.0, 1.0,
  41. };
  42.  
  43. int LAPLACIAN_KERNEL[9] = { 0.0, -1.0, 0.0,
  44. -1.0, 4.0, -1.0,
  45. 0.0, -1.0, 0.0
  46. };
  47.  
  48. int LAPLACIAN_GAUSSIAN_KERNEL[25] = {
  49. 0.0, 0.0, -1.0, 0.0, 0.0,
  50. 0.0, -1.0, -2.0, -1.0, 0.0,
  51. -1.0, -2.0, 16.0, -2.0, -1.0,
  52. 0.0, -1.0, -2.0, -1.0, 0.0,
  53. 0.0, 0.0, -1.0, 0.0, 0.0,
  54. };
  55.  
  56. uint8_t filter_operator(const int fullIndex, uint8_t * image)
  57. {
  58. #pragma HLS inline // Inliner la fonction lui permet d'etre "copie-coller" lorsqu elle est appelle
  59. // et ainsi faciliter le pipelinage de la boucle principale
  60. /*la fonction peut avoir 3 signatures différentes, selon vos différentes modifications:
  61. * uint8_t filter_operator(const int fullIndex, uint8_t * image)
  62. * uint8_t filter_operator(const int fullIndex, uint8_t image[IMG_HEIGHT * IMG_WIDTH])
  63. * uint8_t filter_operator(const int col, const int row, uint8_t image[IMG_HEIGHT][IMG_WIDTH])
  64. *
  65. * Les deux premieres sont assez equivalentes, mais la derniere permet d'acceder à l'image comme un
  66. * tableau 2D. Par contre, un tableau 2D doit alors lui etre passe, ce qui n'est pas evident considerant
  67. * que les entrees de la fonction filtrer() sont 1D. Cependant, si pour une raison ou une autre
  68. * un buffer-cache intermediaire etait utilise, celui-ci pourrait etre 2D...
  69. */
  70.  
  71. return 0;
  72. }
  73.  
  74.  
  75. void filter(uint8_t inter_pix[IMG_WIDTH * IMG_HEIGHT], unsigned out_pix[IMG_WIDTH * IMG_HEIGHT])
  76. {
  77. /* On demande à HLS de nous synthetiser des maitres AXI que l'on connectera à la memoire principale.
  78. * Ainsi, le CPU n'a pas besoin de transferer l'image au filtre: c'est le filtre qui va chercher l'image
  79. * dans la memoire principale (DDR de la carte) et ecrit le resultat dans cette meme memoire.
  80. * Un esclave AXI-Lite est aussi cree, accessible par le CPU, pour informer le filtre des adresses
  81. * auxquelles il doit aller chercher et ecrire l'image, lui dire de demarrer ou d'arreter, etc.
  82. */
  83. // ***** LES 3 LIGNES SUIVANTES DOIVENT ETRE DECOMMENTEES UNE FOIS LES QUESTIONS INITIALES COMPLETE!! ******
  84. #pragma HLS INTERFACE m_axi port=inter_pix offset=slave bundle=gmem0
  85. #pragma HLS INTERFACE m_axi port=out_pix offset=slave bundle=gmem1
  86. #pragma HLS INTERFACE s_axilite port=return
  87. #pragma HLS inline
  88. OneToFourPixels fourWide;
  89.  
  90. for (int i = 0; i < IMG_SIZE; i++) {
  91.  
  92. fourWide.pix[0] = applyFilter(inter_pix, i, Sobel);
  93. fourWide.pix[1] = fourWide.pix[0];
  94. fourWide.pix[2] = fourWide.pix[0];
  95. fourWide.pix[3] = fourWide.pix[0];
  96.  
  97. out_pix[i] = fourWide.full;
  98. }
  99. }
  100.  
  101. float getTangent(float x, float y)
  102. {
  103. #pragma HLS inline
  104.  
  105. float val = ABS(x) + ABS(y);
  106.  
  107. val = (255 - (uint8_t)(val));
  108. if (val > 200) {
  109. val = 255;
  110. }
  111. else if (val < 100) {
  112. val = 0;
  113. }
  114. return val;
  115. }
  116.  
  117. int getFilterSize(enum filter filter)
  118. {
  119. #pragma HLS inline
  120.  
  121. switch (filter)
  122. {
  123. case BoxBlur3:
  124. return 3;
  125. case BoxBlur5:
  126. return 5;
  127. case GaussianBlur:
  128. return 7;
  129. case Sobel:
  130. return 3;
  131. case Laplacian:
  132. return 3;
  133. case LaplacianGaussian:
  134. return 5;
  135. default:
  136. return 0;
  137. }
  138. }
  139.  
  140. void applyKernel(enum filter filter, uint8_t pixel, int filterPos, float newPixelValue[2])
  141. {
  142. #pragma HLS inline
  143. switch (filter)
  144. {
  145. case BoxBlur3:
  146. newPixelValue[0] += (float)pixel * BOX_BLUR_KERNEL_3[filterPos];
  147. break;
  148. case BoxBlur5:
  149. newPixelValue[0] += (float)pixel * BOX_BLUR_KERNEL_5[filterPos];
  150. break;
  151. case GaussianBlur:
  152. newPixelValue[0] += (float)pixel * GAUSSIAN_BLUR_KERNEL[filterPos];
  153. break;
  154. case Sobel:
  155. newPixelValue[0] += pixel * SOBEL_KERNEL_X[filterPos];
  156. newPixelValue[1] += pixel * SOBEL_KERNEL_Y[filterPos];
  157. break;
  158. case Laplacian:
  159. newPixelValue[0] += pixel * LAPLACIAN_KERNEL[filterPos];
  160. break;
  161. case LaplacianGaussian:
  162. newPixelValue[0] += pixel * LAPLACIAN_GAUSSIAN_KERNEL[filterPos];
  163. break;
  164. default:
  165. break;
  166. }
  167. }
  168.  
  169. uint8_t applyFilter(uint8_t imageIn[IMG_SIZE], int curIndex, enum filter filter)
  170. {
  171. #pragma HLS inline
  172.  
  173. int filterSize = getFilterSize(filter);
  174.  
  175. float newPixelValue[2] = { 0.0, 0.0 };
  176. #pragma HLS ARRAY_PARTITION variable=newPixelValue complete dim=1
  177.  
  178. int curImageRow = curIndex / IMG_WIDTH;
  179. int curImageCol = curIndex - (curImageRow * IMG_WIDTH);
  180.  
  181. for (int i = 0; i < filterSize * filterSize; i++)
  182. {
  183. #pragma HLS unroll factor = 3
  184. int curFilterRow = i / filterSize;
  185. int curFilterCol = i - (curFilterRow * filterSize);
  186.  
  187. int targetedRow = curImageRow - (filterSize / 2) + curFilterRow;
  188. int targetedCol = curImageCol - (filterSize / 2) + curFilterCol;
  189.  
  190. if (targetedRow >= 0 && targetedRow < IMG_HEIGHT && targetedCol >= 0 && targetedCol < IMG_WIDTH)
  191. {
  192. applyKernel(filter, imageIn[(targetedRow * IMG_WIDTH) + targetedCol], (curFilterRow * filterSize) + curFilterCol, newPixelValue);
  193. }
  194. }
  195.  
  196. uint8_t val = (uint8_t)newPixelValue[0];
  197. return filter != Sobel ? val : getTangent(newPixelValue[0], newPixelValue[1]);
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement