Tark_Wight

Untitled

Apr 2nd, 2023
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.84 KB | None | 0 0
  1. #include <immintrin.h>
  2.  
  3. void gaussianFilter(const char* inputFilename, const char* outputFilename, int radius)
  4. {
  5. std::vector<unsigned char> input_image;
  6. unsigned int width, height;
  7.  
  8. // загрузка входного изображения
  9. unsigned error = lodepng::decode(input_image, width, height, inputFilename);
  10. if (error)
  11. std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
  12.  
  13. // создание копии входного изображения
  14. std::vector<unsigned char> output_image(input_image.size());
  15.  
  16. // настройка параметров фильтра
  17. float sigma = radius / 3.0f;
  18. int size = radius * 2 + 1;
  19. std::vector<float> kernel(size * size);
  20. float sum = 0.0f;
  21. for (int y = -radius; y <= radius; y++)
  22. {
  23. for (int x = -radius; x <= radius; x++)
  24. {
  25. float value = std::exp(-(x * x + y * y) / (2.0f * sigma * sigma));
  26. kernel[(y + radius) * size + (x + radius)] = value;
  27. sum += value;
  28. }
  29. }
  30. for (int i = 0; i < size * size; i++)
  31. {
  32. kernel[i] /= sum;
  33. }
  34.  
  35. // фильтрация изображения
  36. __m256i zero = _mm256_setzero_si256();
  37. int byte_step = 4;
  38. int vector_size = 32;
  39. for (unsigned int y = radius; y < height - radius; y++)
  40. {
  41. for (unsigned int x = radius; x < width - radius; x += vector_size)
  42. {
  43. for (unsigned int c = 0; c < 4; c++)
  44. {
  45. float accumulator[vector_size];
  46. __m256 sum_vector = _mm256_setzero_ps();
  47. for (int ky = -radius; ky <= radius; ky++)
  48. {
  49. for (int kx = -radius; kx <= radius; kx++)
  50. {
  51. float value = kernel[(ky + radius) * size + (kx + radius)];
  52. int index = ((y + ky) * width + (x + kx)) * 4 + c;
  53. __m256i pixel = _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*) &input_image[index]));
  54. __m256 kernel_vector = _mm256_set1_ps(value);
  55. __m256 pixel_float = _mm256_cvtepi32_ps(pixel);
  56. __m256 weighted_pixel = _mm256_mul_ps(pixel_float, kernel_vector);
  57. sum_vector = _mm256_add_ps(sum_vector, weighted_pixel);
  58. }
  59. }
  60. _mm256_storeu_ps(&accumulator[0], sum_vector);
  61. for (int i = 0; i < vector_size; i++)
  62. {
  63. int index = (y * width + x + i) * 4 + c;
  64. output_image[index] = (unsigned char)accumulator[i];
  65. }
  66. }
  67. }
  68. }
  69.  
  70. // сохранение выходного изображения
  71. error = lodepng::encode(outputFilename,
  72.  
Advertisement
Add Comment
Please, Sign In to add comment