Advertisement
Tark_Wight

Untitled

Apr 2nd, 2023
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.32 KB | None | 0 0
  1. #include <algorithm>
  2. #include <intrin.h>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <string>
  6. #include <vector>
  7. #include <ctime>
  8. #include "lodepng.cpp"
  9. #include "lodepng.h"
  10.  
  11.  
  12. using namespace std;
  13.  
  14. //@@@@@@@@@@@@@@@@@@@@ Consistent Filter @@@@@@@@@@@@@@@@@@@@
  15.  
  16. void negateImage(const char* inputFilename, const char* outputFilename) {
  17. // Загружаем изображение
  18. unsigned error;
  19. unsigned char* image;
  20. unsigned width, height;
  21.  
  22. error = lodepng_decode24_file(&image, &width, &height, inputFilename);
  23. if (error) {
  24. std::cerr << "Failed to load image: " << lodepng_error_text(error) << endl;
  25. return;
  26. }
  27.  
  28. // Фильтр негатива
  29. for (unsigned y = 0; y < height; y++) {
  30. for (unsigned x = 0; x < width; x++) {
  31. unsigned index = (y * width + x) * 3;
  32. image[index + 0] = 255 - image[index + 0];
  33. image[index + 1] = 255 - image[index + 1];
  34. image[index + 2] = 255 - image[index + 2];
  35. }
  36. }
  37.  
  38. // Сохраняем изображение
  39. error = lodepng_encode24_file(outputFilename, image, width, height);
  40. if (error) {
  41. std::cerr << "Failed to save image: " << lodepng_error_text(error) << endl;
  42. return;
  43. }
  44.  
  45. // Освобождаем память
  46. free(image);
  47. }
  48.  
  49. unsigned char getMedian(std::vector<unsigned char>&values) {
  50. std::sort(values.begin(), values.end());
  51. return values[values.size() / 2];
  52. }
  53. void applyMedianFilter(std::vector<unsigned char>&image, int width, int height, int channels, int filterSize) {
  54. std::vector<unsigned char> result(image.size());
  55.  
  56. int radius = filterSize / 2;
  57.  
  58. for (int y = 0; y < height; y++) {
  59. for (int x = 0; x < width; x++) {
  60. for (int c = 0; c < channels; c++) {
  61. std::vector<unsigned char> values;
  62.  
  63. for (int i = -radius; i <= radius; i++) {
  64. for (int j = -radius; j <= radius; j++) {
  65. int px = std::min(std::max(x + j, 0), width - 1);
  66. int py = std::min(std::max(y + i, 0), height - 1);
  67.  
  68. values.push_back(image[(py * width + px) * channels + c]);
  69. }
  70. }
  71.  
  72. result[(y * width + x) * channels + c] = getMedian(values);
  73. }
  74. }
  75. }
  76.  
  77. image = result;
  78. }
  79. void medianFilter(const char* inputFilename, const char* outputFilename, int filterSize) {
  80. std::vector<unsigned char> image;
  81. unsigned width, height;
  82.  
  83. // Загружаем изображение
  84. unsigned error = lodepng::decode(image, width, height, inputFilename);
  85.  
  86. if (error) {
  87. std::cerr << "Error decoding image: " << lodepng_error_text(error) << std::endl;
  88. return;
  89. }
  90.  
  91. // Применяем медианный фильтр
  92. applyMedianFilter(image, width, height, 4, filterSize);
  93.  
  94. // Сохраняем изображение
  95. error = lodepng::encode(outputFilename, image, width, height);
  96.  
  97. if (error) {
  98. std::cerr << "Error encoding image: " << lodepng_error_text(error) << std::endl;
  99. return;
  100. }
  101. }
  102.  
  103. void gaussianFilter(const char* inputFilename, const char* outputFilename, int radius)
  104. {
  105. std::vector<unsigned char> input_image;
  106. unsigned int width, height;
  107.  
  108. // загрузка входного изображения
  109. unsigned error = lodepng::decode(input_image, width, height, inputFilename);
  110. if (error)
  111. std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
  112.  
  113. // создание копии входного изображения
  114. std::vector<unsigned char> output_image(input_image.size());
  115.  
  116. // настройка параметров фильтра
  117. float sigma = radius / 3.0f;
  118. int size = radius * 2 + 1;
  119. std::vector<float> kernel(size * size);
  120. float sum = 0.0f;
  121. for (int y = -radius; y <= radius; y++)
  122. {
  123. for (int x = -radius; x <= radius; x++)
  124. {
  125. float value = std::exp(-(x * x + y * y) / (2.0f * sigma * sigma));
  126. kernel[(y + radius) * size + (x + radius)] = value;
  127. sum += value;
  128. }
  129. }
  130. for (int i = 0; i < size * size; i++)
  131. {
  132. kernel[i] /= sum;
  133. }
  134.  
  135. // фильтрация изображения
  136. for (unsigned int y = radius; y < height - radius; y++)
  137. {
  138. for (unsigned int x = radius; x < width - radius; x++)
  139. {
  140. for (unsigned int c = 0; c < 4; c++)
  141. {
  142. float accumulator = 0.0f;
  143. for (int ky = -radius; ky <= radius; ky++)
  144. {
  145. for (int kx = -radius; kx <= radius; kx++)
  146. {
  147. float value = kernel[(ky + radius) * size + (kx + radius)];
  148. unsigned int index = ((y + ky) * width + (x + kx)) * 4 + c;
  149. accumulator += input_image[index] * value;
  150. }
  151. }
  152. unsigned int index = (y * width + x) * 4 + c;
  153. output_image[index] = (unsigned char)accumulator;
  154. }
  155. }
  156. }
  157.  
  158. // сохранение выходного изображения
  159. error = lodepng::encode(outputFilename, output_image, width, height);
  160. if (error)
  161. std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
  162. }
  163.  
  164.  
  165. //@@@@@@@@@@@@@@@@@@@@ Vectorisation Filter @@@@@@@@@@@@@@@@@@@@
  166.  
  167.  
  168. //@@@@@@@@@@@@@@@@@@@@ OpenMP Filter @@@@@@@@@@@@@@@@@@@@
  169. void negateImageOMP(const char* inputFilename, const char* outputFilename) {
  170. // Загружаем изображение
  171. unsigned error;
  172. unsigned char* image;
  173. unsigned width, height;
  174.  
  175. error = lodepng_decode24_file(&image, &width, &height, inputFilename);
  176. if (error) {
  177. std::cerr << "Failed to load image: " << lodepng_error_text(error) << endl;
  178. return;
  179. }
  180.  
  181. // Фильтр негатива
  182. #pragma omp parallel for collapse(2)
  183. for (int y = 0; y < height; y++) {
  184. for (int x = 0; x < width; x++) {
  185. unsigned index = (y * width + x) * 3;
  186. image[index + 0] = 255 - image[index + 0];
  187. image[index + 1] = 255 - image[index + 1];
  188. image[index + 2] = 255 - image[index + 2];
  189. }
  190. }
  191.  
  192. // Сохраняем изображение
  193. error = lodepng_encode24_file(outputFilename, image, width, height);
  194. if (error) {
  195. std::cerr << "Failed to save image: " << lodepng_error_text(error) << endl;
  196. return;
  197. }
  198.  
  199. // Освобождаем память
  200. free(image);
  201. }
  202.  
  203. unsigned char getMedianOMP(std::vector<unsigned char>& values) {
  204. std::sort(values.begin(), values.end());
  205. return values[values.size() / 2];
  206. }
  207. void applyMedianFilterOMP(std::vector<unsigned char>& image, int width, int height, int channels, int filterSize) {
  208. std::vector<unsigned char> result(image.size());
  209.  
  210. int radius = filterSize / 2;
  211. #pragma omp parallel for collapse(5)
  212. for (int y = 0; y < height; y++) {
  213. for (int x = 0; x < width; x++) {
  214. for (int c = 0; c < channels; c++) {
  215. std::vector<unsigned char> values;
  216.  
  217. for (int i = -radius; i <= radius; i++) {
  218. for (int j = -radius; j <= radius; j++) {
  219. int px = std::min(std::max(x + j, 0), width - 1);
  220. int py = std::min(std::max(y + i, 0), height - 1);
  221.  
  222. values.push_back(image[(py * width + px) * channels + c]);
  223. }
  224. }
  225.  
  226. result[(y * width + x) * channels + c] = getMedianOMP(values);
  227. }
  228. }
  229. }
  230.  
  231. image = result;
  232. }
  233. void medianFilterOMP(const char* inputFilename, const char* outputFilename, int filterSize) {
  234. std::vector<unsigned char> image;
  235. unsigned width, height;
  236.  
  237. // Загружаем изображение
  238. unsigned error = lodepng::decode(image, width, height, inputFilename);
  239.  
  240. if (error) {
  241. std::cerr << "Error decoding image: " << lodepng_error_text(error) << std::endl;
  242. return;
  243. }
  244.  
  245. // Применяем медианный фильтр
  246. applyMedianFilterOMP(image, width, height, 4, filterSize);
  247.  
  248. // Сохраняем изображение
  249. error = lodepng::encode(outputFilename, image, width, height);
  250.  
  251. if (error) {
  252. std::cerr << "Error encoding image: " << lodepng_error_text(error) << std::endl;
  253. return;
  254. }
  255. }
  256.  
  257. void gaussianFilterOMP(const char* inputFilename, const char* outputFilename, int radius) {
  258. std::vector<unsigned char> input_image;
  259. unsigned int width, height;
  260.  
  261. // загрузка входного изображения
  262. unsigned error = lodepng::decode(input_image, width, height, inputFilename);
  263. if (error) {
  264. std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
  265. }
  266. // создание копии входного изображения
  267. std::vector<unsigned char> output_image(input_image.size());
  268.  
  269. // настройка параметров фильтра
  270. float sigma = radius / 3.0f;
  271. int size = radius * 2 + 1;
  272. std::vector<float> kernel(size * size);
  273. float sum = 0.0f;
  274.  
  275. #pragma omp parallel for collapse(2)
  276. for (int y = -radius; y <= radius; y++) {
  277. for (int x = -radius; x <= radius; x++) {
  278. float value = std::exp(-(x * x + y * y) / (2.0f * sigma * sigma));
  279. kernel[(y + radius) * size + (x + radius)] = value;
  280. sum += value;
  281. }
  282. }
  283. for (int i = 0; i < size * size; i++) {
  284. kernel[i] /= sum;
  285. }
  286.  
  287. // фильтрация изображения
  288. #pragma omp parallel for collapse(5)
  289. for (int y = radius; y < height - radius; y++) {
  290. for (int x = radius; x < width - radius; x++) {
  291. for (int c = 0; c < 4; c++) {
  292. float accumulator = 0.0f;
  293. for (int ky = -radius; ky <= radius; ky++) {
  294. for (int kx = -radius; kx <= radius; kx++) {
  295. float value = kernel[(ky + radius) * size + (kx + radius)];
  296. unsigned int index = ((y + ky) * width + (x + kx)) * 4 + c;
  297. accumulator += input_image[index] * value;
  298. }
  299. }
  300. unsigned int index = (y * width + x) * 4 + c;
  301. output_image[index] = (unsigned char)accumulator;
  302. }
  303. }
  304. }
  305.  
  306. // сохранение выходного изображения
  307. error = lodepng::encode(outputFilename, output_image, width, height);
  308. if (error) {
  309. std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
  310. }
  311. }
  312.  
  313.  
  314. void userConsistentMedianFilter() {
  315. clock_t start = clock();
  316. medianFilter("input.png", "outputMedian.png", 10);
  317. clock_t end = clock();
  318. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  319. std::cout << "Время выполнения функции медианного фильтра: " << elapsed_time << " секунд." << std::endl;
  320.  
  321. }
  322. void userConsistentGaussianFilter() {
  323. clock_t start = clock();
  324. gaussianFilter("input.png", "outputGauss.png", 10);
  325. clock_t end = clock();
  326. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  327. std::cout << "Время выполнения функции фильтра размытия по Гауссу: " << elapsed_time << " секунд." << std::endl;
  328.  
  329. }
  330. void userConsistentNegativeFilter() {
  331. clock_t start = clock();
  332. // Задаем имена входного и выходного файлов
  333. const char* inputFilename = "input.png";
  334. const char* outputFilename = "outputNegative.png";
  335. // Фильтр негатива
  336. negateImage(inputFilename, outputFilename);
  337. clock_t end = clock();
  338. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  339. std::cout << "Время выполнения функции негативного фильтра: " << elapsed_time << " секунд." << std::endl;
  340. }
  341. void userConsistentFilter() {
  342. userConsistentMedianFilter();
  343. userConsistentGaussianFilter();
  344. userConsistentNegativeFilter();
  345. }
  346.  
  347.  
  348. void userOMPMedianFilter() {
  349. clock_t start = clock();
  350. medianFilterOMP("input.png", "outputMedianOMP.png", 10);
  351. clock_t end = clock();
  352. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  353. std::cout << "Время выполнения функции медианного фильтра: " << elapsed_time << " секунд." << std::endl;
  354.  
  355. }
  356. void userOMPGaussianFilter() {
  357. clock_t start = clock();
  358. gaussianFilterOMP("input.png", "outputGaussOMP.png", 10);
  359. clock_t end = clock();
  360. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  361. std::cout << "Время выполнения функции фильтра размытия по Гауссу: " << elapsed_time << " секунд." << std::endl;
  362.  
  363. }
  364. void userOMPNegativeFilter() {
  365. clock_t start = clock();
  366. // Задаем имена входного и выходного файлов
  367. const char* inputFilename = "input.png";
  368. const char* outputFilename = "outputNegativeOMP.png";
  369. // Фильтр негатива
  370. negateImageOMP(inputFilename, outputFilename);
  371. clock_t end = clock();
  372. double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
  373. std::cout << "Время выполнения функции негативного фильтра: " << elapsed_time << " секунд." << std::endl;
  374. }
  375. void userOPMFilter() {
  376. userOMPMedianFilter();
  377. userOMPGaussianFilter();
  378. userOMPNegativeFilter();
  379. }
  380.  
  381.  
  382. int main() {
  383. setlocale(LC_ALL, "Russian");
  384. std::cout << "Последовательный метод:\n";
  385. userConsistentFilter();
  386. std::cout << "\n\n";
  387. std::cout << "OpenMP:\n";
  388. userOPMFilter();
  389.  
  390. return 0;
  391. }
  392.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement