Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <intrin.h>
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include <ctime>
- #include "lodepng.cpp"
- #include "lodepng.h"
- using namespace std;
- //@@@@@@@@@@@@@@@@@@@@ Consistent Filter @@@@@@@@@@@@@@@@@@@@
- void negateImage(const char* inputFilename, const char* outputFilename) {
- // Загружаем изображение
- unsigned error;
- unsigned char* image;
- unsigned width, height;
- error = lodepng_decode24_file(&image, &width, &height, inputFilename);
- if (error) {
- std::cerr << "Failed to load image: " << lodepng_error_text(error) << endl;
- return;
- }
- // Фильтр негатива
- for (unsigned y = 0; y < height; y++) {
- for (unsigned x = 0; x < width; x++) {
- unsigned index = (y * width + x) * 3;
- image[index + 0] = 255 - image[index + 0];
- image[index + 1] = 255 - image[index + 1];
- image[index + 2] = 255 - image[index + 2];
- }
- }
- // Сохраняем изображение
- error = lodepng_encode24_file(outputFilename, image, width, height);
- if (error) {
- std::cerr << "Failed to save image: " << lodepng_error_text(error) << endl;
- return;
- }
- // Освобождаем память
- free(image);
- }
- unsigned char getMedian(std::vector<unsigned char>&values) {
- std::sort(values.begin(), values.end());
- return values[values.size() / 2];
- }
- void applyMedianFilter(std::vector<unsigned char>&image, int width, int height, int channels, int filterSize) {
- std::vector<unsigned char> result(image.size());
- int radius = filterSize / 2;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- for (int c = 0; c < channels; c++) {
- std::vector<unsigned char> values;
- for (int i = -radius; i <= radius; i++) {
- for (int j = -radius; j <= radius; j++) {
- int px = std::min(std::max(x + j, 0), width - 1);
- int py = std::min(std::max(y + i, 0), height - 1);
- values.push_back(image[(py * width + px) * channels + c]);
- }
- }
- result[(y * width + x) * channels + c] = getMedian(values);
- }
- }
- }
- image = result;
- }
- void medianFilter(const char* inputFilename, const char* outputFilename, int filterSize) {
- std::vector<unsigned char> image;
- unsigned width, height;
- // Загружаем изображение
- unsigned error = lodepng::decode(image, width, height, inputFilename);
- if (error) {
- std::cerr << "Error decoding image: " << lodepng_error_text(error) << std::endl;
- return;
- }
- // Применяем медианный фильтр
- applyMedianFilter(image, width, height, 4, filterSize);
- // Сохраняем изображение
- error = lodepng::encode(outputFilename, image, width, height);
- if (error) {
- std::cerr << "Error encoding image: " << lodepng_error_text(error) << std::endl;
- return;
- }
- }
- 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;
- }
- // фильтрация изображения
- for (unsigned int y = radius; y < height - radius; y++)
- {
- for (unsigned int x = radius; x < width - radius; x++)
- {
- for (unsigned int c = 0; c < 4; c++)
- {
- float accumulator = 0.0f;
- for (int ky = -radius; ky <= radius; ky++)
- {
- for (int kx = -radius; kx <= radius; kx++)
- {
- float value = kernel[(ky + radius) * size + (kx + radius)];
- unsigned int index = ((y + ky) * width + (x + kx)) * 4 + c;
- accumulator += input_image[index] * value;
- }
- }
- unsigned int index = (y * width + x) * 4 + c;
- output_image[index] = (unsigned char)accumulator;
- }
- }
- }
- // сохранение выходного изображения
- error = lodepng::encode(outputFilename, output_image, width, height);
- if (error)
- std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
- }
- //@@@@@@@@@@@@@@@@@@@@ Vectorisation Filter @@@@@@@@@@@@@@@@@@@@
- //@@@@@@@@@@@@@@@@@@@@ OpenMP Filter @@@@@@@@@@@@@@@@@@@@
- void negateImageOMP(const char* inputFilename, const char* outputFilename) {
- // Загружаем изображение
- unsigned error;
- unsigned char* image;
- unsigned width, height;
- error = lodepng_decode24_file(&image, &width, &height, inputFilename);
- if (error) {
- std::cerr << "Failed to load image: " << lodepng_error_text(error) << endl;
- return;
- }
- // Фильтр негатива
- #pragma omp parallel for collapse(2)
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- unsigned index = (y * width + x) * 3;
- image[index + 0] = 255 - image[index + 0];
- image[index + 1] = 255 - image[index + 1];
- image[index + 2] = 255 - image[index + 2];
- }
- }
- // Сохраняем изображение
- error = lodepng_encode24_file(outputFilename, image, width, height);
- if (error) {
- std::cerr << "Failed to save image: " << lodepng_error_text(error) << endl;
- return;
- }
- // Освобождаем память
- free(image);
- }
- unsigned char getMedianOMP(std::vector<unsigned char>& values) {
- std::sort(values.begin(), values.end());
- return values[values.size() / 2];
- }
- void applyMedianFilterOMP(std::vector<unsigned char>& image, int width, int height, int channels, int filterSize) {
- std::vector<unsigned char> result(image.size());
- int radius = filterSize / 2;
- #pragma omp parallel for collapse(5)
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- for (int c = 0; c < channels; c++) {
- std::vector<unsigned char> values;
- for (int i = -radius; i <= radius; i++) {
- for (int j = -radius; j <= radius; j++) {
- int px = std::min(std::max(x + j, 0), width - 1);
- int py = std::min(std::max(y + i, 0), height - 1);
- values.push_back(image[(py * width + px) * channels + c]);
- }
- }
- result[(y * width + x) * channels + c] = getMedianOMP(values);
- }
- }
- }
- image = result;
- }
- void medianFilterOMP(const char* inputFilename, const char* outputFilename, int filterSize) {
- std::vector<unsigned char> image;
- unsigned width, height;
- // Загружаем изображение
- unsigned error = lodepng::decode(image, width, height, inputFilename);
- if (error) {
- std::cerr << "Error decoding image: " << lodepng_error_text(error) << std::endl;
- return;
- }
- // Применяем медианный фильтр
- applyMedianFilterOMP(image, width, height, 4, filterSize);
- // Сохраняем изображение
- error = lodepng::encode(outputFilename, image, width, height);
- if (error) {
- std::cerr << "Error encoding image: " << lodepng_error_text(error) << std::endl;
- return;
- }
- }
- void gaussianFilterOMP(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;
- #pragma omp parallel for collapse(2)
- 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;
- }
- // фильтрация изображения
- #pragma omp parallel for collapse(5)
- for (int y = radius; y < height - radius; y++) {
- for (int x = radius; x < width - radius; x++) {
- for (int c = 0; c < 4; c++) {
- float accumulator = 0.0f;
- for (int ky = -radius; ky <= radius; ky++) {
- for (int kx = -radius; kx <= radius; kx++) {
- float value = kernel[(ky + radius) * size + (kx + radius)];
- unsigned int index = ((y + ky) * width + (x + kx)) * 4 + c;
- accumulator += input_image[index] * value;
- }
- }
- unsigned int index = (y * width + x) * 4 + c;
- output_image[index] = (unsigned char)accumulator;
- }
- }
- }
- // сохранение выходного изображения
- error = lodepng::encode(outputFilename, output_image, width, height);
- if (error) {
- std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
- }
- }
- void userConsistentMedianFilter() {
- clock_t start = clock();
- medianFilter("input.png", "outputMedian.png", 10);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции медианного фильтра: " << elapsed_time << " секунд." << std::endl;
- }
- void userConsistentGaussianFilter() {
- clock_t start = clock();
- gaussianFilter("input.png", "outputGauss.png", 10);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции фильтра размытия по Гауссу: " << elapsed_time << " секунд." << std::endl;
- }
- void userConsistentNegativeFilter() {
- clock_t start = clock();
- // Задаем имена входного и выходного файлов
- const char* inputFilename = "input.png";
- const char* outputFilename = "outputNegative.png";
- // Фильтр негатива
- negateImage(inputFilename, outputFilename);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции негативного фильтра: " << elapsed_time << " секунд." << std::endl;
- }
- void userConsistentFilter() {
- userConsistentMedianFilter();
- userConsistentGaussianFilter();
- userConsistentNegativeFilter();
- }
- void userOMPMedianFilter() {
- clock_t start = clock();
- medianFilterOMP("input.png", "outputMedianOMP.png", 10);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции медианного фильтра: " << elapsed_time << " секунд." << std::endl;
- }
- void userOMPGaussianFilter() {
- clock_t start = clock();
- gaussianFilterOMP("input.png", "outputGaussOMP.png", 10);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции фильтра размытия по Гауссу: " << elapsed_time << " секунд." << std::endl;
- }
- void userOMPNegativeFilter() {
- clock_t start = clock();
- // Задаем имена входного и выходного файлов
- const char* inputFilename = "input.png";
- const char* outputFilename = "outputNegativeOMP.png";
- // Фильтр негатива
- negateImageOMP(inputFilename, outputFilename);
- clock_t end = clock();
- double elapsed_time = double(end - start) / CLOCKS_PER_SEC;
- std::cout << "Время выполнения функции негативного фильтра: " << elapsed_time << " секунд." << std::endl;
- }
- void userOPMFilter() {
- userOMPMedianFilter();
- userOMPGaussianFilter();
- userOMPNegativeFilter();
- }
- int main() {
- setlocale(LC_ALL, "Russian");
- std::cout << "Последовательный метод:\n";
- userConsistentFilter();
- std::cout << "\n\n";
- std::cout << "OpenMP:\n";
- userOPMFilter();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement