Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <immintrin.h>
- void gaussianFilter(const char* inputFilename, const char* outputFilename, int radius)
- {
- std::vector<unsigned char> input_image;
- unsigned int width, height;
- // загрузка входного изображения
- unsigned error = lodepng::decode(input_image, width, height, inputFilename);
- if (error)
- std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
- // создание копии входного изображения
- std::vector<unsigned char> output_image(input_image.size());
- // настройка параметров фильтра
- float sigma = radius / 3.0f;
- int size = radius * 2 + 1;
- std::vector<float> kernel(size * size);
- float sum = 0.0f;
- for (int y = -radius; y <= radius; y++)
- {
- for (int x = -radius; x <= radius; x++)
- {
- float value = std::exp(-(x * x + y * y) / (2.0f * sigma * sigma));
- kernel[(y + radius) * size + (x + radius)] = value;
- sum += value;
- }
- }
- for (int i = 0; i < size * size; i++)
- {
- kernel[i] /= sum;
- }
- // фильтрация изображения
- __m256i zero = _mm256_setzero_si256();
- int byte_step = 4;
- int vector_size = 32;
- for (unsigned int y = radius; y < height - radius; y++)
- {
- for (unsigned int x = radius; x < width - radius; x += vector_size)
- {
- for (unsigned int c = 0; c < 4; c++)
- {
- float accumulator[vector_size];
- __m256 sum_vector = _mm256_setzero_ps();
- for (int ky = -radius; ky <= radius; ky++)
- {
- for (int kx = -radius; kx <= radius; kx++)
- {
- float value = kernel[(ky + radius) * size + (kx + radius)];
- int index = ((y + ky) * width + (x + kx)) * 4 + c;
- __m256i pixel = _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*) &input_image[index]));
- __m256 kernel_vector = _mm256_set1_ps(value);
- __m256 pixel_float = _mm256_cvtepi32_ps(pixel);
- __m256 weighted_pixel = _mm256_mul_ps(pixel_float, kernel_vector);
- sum_vector = _mm256_add_ps(sum_vector, weighted_pixel);
- }
- }
- _mm256_storeu_ps(&accumulator[0], sum_vector);
- for (int i = 0; i < vector_size; i++)
- {
- int index = (y * width + x + i) * 4 + c;
- output_image[index] = (unsigned char)accumulator[i];
- }
- }
- }
- }
- // сохранение выходного изображения
- error = lodepng::encode(outputFilename,
Advertisement
Add Comment
Please, Sign In to add comment