Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #define min(x, y) x < y ? x : y
  6. #define max(x, y) x > y ? x : y
  7. #define step(x) x > 128 ? 255 : 0
  8.  
  9. #define pi 3.1415926535897932384626433832795
  10.  
  11. FILE* fileIn;
  12. FILE* fileOut;
  13.  
  14. #pragma pack(push, 1)
  15. struct bmh_file
  16. {
  17. unsigned short bf_type;
  18. unsigned int bf_size;
  19. unsigned short bf_reversed_one;
  20. unsigned short bf_reversed_two;
  21. unsigned int bf_off_bits;
  22. };
  23.  
  24. struct bmh_info {
  25. unsigned int size;
  26. unsigned int widht;
  27. unsigned int height;
  28. unsigned short planes;
  29. unsigned short bit_count;
  30. unsigned int compression;
  31. unsigned int size_image;
  32. unsigned int x_pels_per_meter;
  33. unsigned int y_pels_per_meter;
  34. unsigned int color_used;
  35. unsigned int color_important;
  36. };
  37. #pragma pack(pop)
  38.  
  39. void correct_input(int argc, char* argv[])
  40. {
  41. int fl = 0;
  42. if (!(argc == 4 && (strcmp(argv[2], "Averaging") == 0 || strcmp(argv[2], "Gauss3") == 0 || strcmp(argv[2], "Gauss5") == 0
  43. || strcmp(argv[2], "SobelX") == 0 || strcmp(argv[2], "SobelY") == 0 || strcmp(argv[2], "ColorWB") == 0) && fopen_s(&fileIn, argv[1], "rb") == 0))
  44. fl = 1;
  45. char extension[] = ".bmp";
  46. // for (int i = 1; i < 5; i++)
  47. // if (argv[3][strlen(argv[3]) - i] != extension[4 - i] || argv[1][strlen(argv[1]) - i] != extension[4 - i])
  48. // fl = 1;
  49. if (fl)
  50. {
  51. printf("Invalid input. Try again.\n");
  52. exit(0);
  53. }
  54. }
  55.  
  56. void to_grey(unsigned char* input_binary_image, int height, int width)
  57. {
  58. for (int i = 0; i < height * width; i++)
  59. {
  60. //unsigned char result = (299 * input_binary_image[i * 3] + 587 * input_binary_image[i * 3 + 1] + 114 * input_binary_image[i * 3 + 2]) / 1000;
  61. unsigned char result = (input_binary_image[i * 3] + input_binary_image[i * 3 + 1] + input_binary_image[i * 3 + 2]) / 3;
  62. input_binary_image[i * 3] = result;
  63. input_binary_image[i * 3 + 1] = result;
  64. input_binary_image[i * 3 + 2] = result;
  65. }
  66. }
  67.  
  68. void average_and_sobel_filter(unsigned char* input_binary_image, int height, int width, char pointer)
  69. {
  70. unsigned char* image_copy = (unsigned char*)malloc(3 * height * width * sizeof(char));
  71. int directions[9];
  72. int a[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1};
  73. int b[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1};
  74. int c[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
  75. int i;
  76. if (pointer == 'x')
  77. for(i = 0; i < 9; i++)
  78. directions[i] = a[i];
  79. else if (pointer == 'y')
  80. for(i = 0; i < 9; i++)
  81. directions[i] = b[i];
  82. else if (pointer == 'a')
  83. for(i = 0; i < 9; i++)
  84. directions[i] = c[i];
  85. for (int i = 0; i < height; i++)
  86. for (int j = 0; j < width; j++)
  87. {
  88. int result[3] = {0, 0, 0};
  89. int divider = 0;
  90.  
  91. for (int iter_dir_x = 0; iter_dir_x < 3; iter_dir_x++)
  92. for (int iter_dir_y = 0; iter_dir_y < 3; iter_dir_y++)
  93. if ((i + iter_dir_x - 1) >= 0 && (i + iter_dir_x - 1) <= (height - 1) && (j + iter_dir_y - 1) >= 0 && (j + iter_dir_y - 1) <= (width - 1))
  94. {
  95. result[0] += input_binary_image[((i + iter_dir_x - 1) * width + j + iter_dir_y - 1) * 3 + 0] * directions[iter_dir_x * 3 + iter_dir_y];
  96. result[1] += input_binary_image[((i + iter_dir_x - 1) * width + j + iter_dir_y - 1) * 3 + 1] * directions[iter_dir_x * 3 + iter_dir_y];
  97. result[2] += input_binary_image[((i + iter_dir_x - 1) * width + j + iter_dir_y - 1) * 3 + 2] * directions[iter_dir_x * 3 + iter_dir_y];
  98. divider += directions[iter_dir_x * 3 + iter_dir_y];
  99. }
  100. if (pointer == 'a')
  101. {
  102. image_copy[(i * width + j) * 3] = result[0] / divider;
  103. image_copy[(i * width + j) * 3 + 1] = result[1] / divider;
  104. image_copy[(i * width + j) * 3 + 2] = result[2] / divider;
  105. }
  106. else
  107. {
  108. int x = step(((result[0] + result[1] + result[2]) / 3));
  109. image_copy[(i * width + j) * 3] = x;
  110. image_copy[(i * width + j) * 3 + 1] = x;
  111. image_copy[(i * width + j) * 3 + 2] = x;
  112. }
  113. }
  114. // if (pointer != 'a')
  115. // fromColorToBlackAndWhiteFilter(image_copy, height, width);
  116. for (int i = 0; i < height * width * 3; i++)
  117. input_binary_image[i] = image_copy[i];
  118.  
  119. free(image_copy);
  120. }
  121.  
  122. void gaussFilter(unsigned char* input_binary_image, int height, int width, int type)
  123. {
  124. double sigma = 0.6;
  125. int size = 2 * type + 1;
  126. double* directions = (double*)malloc(size * size * sizeof(double));
  127.  
  128. for (int x = 0; x < size; x++)
  129. for (int y = 0; y < size; y++)
  130. directions[x * size + y] = 1 / sqrt(2 * pi * sigma) * exp(-(x * x + y * y) / (2 * sigma * sigma));
  131.  
  132. unsigned char* image_copy = (unsigned char*)malloc(3 * height * width * sizeof(unsigned char));
  133.  
  134. // if (type == 1) //3*3
  135. // {
  136. for (int i = 0; i < height; i++)
  137. for (int j = 0; j < width; j++)
  138. {
  139. double result[3] = { 0, 0, 0 };
  140. int left, right, down, up;
  141. double divisor = 0;
  142. for (int k = 0; k < 3; k++)
  143. for (int iter_dir_x = 0; iter_dir_x < size; iter_dir_x++)
  144. for (int iter_dir_y = 0; iter_dir_y < size; iter_dir_y++)
  145. if ((i + iter_dir_x - 1) >= 0 && (i + iter_dir_x - 1) <= (height - 1) && (j + iter_dir_y - 1) >= 0 && (j + iter_dir_y - 1) <= (width - 1))
  146. {
  147. result[k] += input_binary_image[((i + iter_dir_x - 1) * width + j + iter_dir_y - 1) * 3 + k] * directions[iter_dir_x * size + iter_dir_y];
  148. divisor += directions[iter_dir_x * size + iter_dir_y];
  149. }
  150. image_copy[(i * width + j) * 3] = (unsigned char)(result[0] / divisor);
  151. image_copy[(i * width + j) * 3 + 1] = (unsigned char)(result[1] / divisor);
  152. image_copy[(i * width + j) * 3 + 2] = (unsigned char)(result[2] / divisor);
  153. }
  154. // }
  155. // else if (size == 2) //5*5
  156. // {
  157. // for (int i = 0; i < height; i++)
  158. // for (int j = 0; j < width; j++)
  159. // {
  160. // double result[3] = { 0, 0, 0 };
  161. // int left, right, down, up;
  162. // double divisor = 0;
  163. // for (int k = 0; k < 3; k++)
  164. // for (int iter_dir_x = 0; iter_dir_x < size; iter_dir_x++)
  165. // for (int iter_dir_y = 0; iter_dir_y < size; iter_dir_y++)
  166. // if ((i + iter_dir_x - 1) >= 0 && (i + iter_dir_x - 1) <= (height - 1) && (j + iter_dir_y - 1) >= 0 && (j + iter_dir_y - 1) <= (width - 1))
  167. // {
  168. // result[k] += input_binary_image[((i + iter_dir_x - 1) * width + j + iter_dir_y - 1) * 3 + k] * directions[iter_dir_x * size + iter_dir_y];
  169. // divisor += directions[iter_dir_x * size + iter_dir_y];
  170. // }
  171. //
  172. // image_copy[(i * width + j) * 3] = (unsigned char)(result[0] / divisor);
  173. // image_copy[(i * width + j) * 3 + 1] = (unsigned char)(result[1] / divisor);
  174. // image_copy[(i * width + j) * 3 + 2] = (unsigned char)(result[2] / divisor);
  175. // }
  176. // }
  177.  
  178. for (int i = 0; i < height * width * 3; i++)
  179. input_binary_image[i] = image_copy[i];
  180.  
  181. free(directions);
  182. free(image_copy);
  183. }
  184.  
  185. void convolution(unsigned char* input_binary_image, struct bmh_file file_header, struct bmh_info info_header)
  186. {
  187. fwrite(&file_header, sizeof(file_header), 1, fileOut);
  188. fwrite(&info_header, sizeof(info_header), 1, fileOut);
  189. for (int i = 0; i < info_header.size_image; i++)
  190. fwrite(&input_binary_image[i], 1, 1, fileOut);
  191. }
  192.  
  193.  
  194. int main(int argc, char* argv[])
  195. {
  196. correct_input(argc, argv);
  197. fopen_s(&fileIn, argv[1], "rb");
  198. fopen_s(&fileOut, argv[3], "wb");
  199. struct bmh_file file_header;
  200. struct bmh_info info_header;
  201. fread(&file_header, sizeof(file_header), 1, fileIn);
  202. fread(&info_header, sizeof(info_header), 1, fileIn);
  203. unsigned char* input_binary_image = (unsigned char*)malloc(info_header.size_image);
  204.  
  205. fseek(fileIn, file_header.bf_off_bits, SEEK_SET);
  206. fread(input_binary_image, 1, info_header.size_image, fileIn);
  207. if (strcmp(argv[2], "Averaging") == 0)
  208. average_and_sobel_filter(input_binary_image, info_header.height, info_header.widht, 'a');
  209. else if (strcmp(argv[2], "Gauss3") == 0)
  210. gaussFilter(input_binary_image, info_header.height, info_header.widht, 1);
  211. else if (strcmp(argv[2], "Gauss5") == 0)
  212. gaussFilter(input_binary_image, info_header.height, info_header.widht, 2);
  213. else if (strcmp(argv[2], "SobelX") == 0)
  214. average_and_sobel_filter(input_binary_image, info_header.height, info_header.widht, 'x');
  215. else if (strcmp(argv[2], "SobelY") == 0)
  216. average_and_sobel_filter(input_binary_image, info_header.height, info_header.widht, 'y');
  217. else if (strcmp(argv[2], "ColorWB") == 0)
  218. to_grey(input_binary_image, info_header.height, info_header.widht);
  219.  
  220. convolution(input_binary_image, file_header, info_header);
  221.  
  222. printf("The program worked successfully");
  223. free(input_binary_image);
  224. fclose(fileIn);
  225. fclose(fileOut);
  226. return 0;
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement