Фильтр для обработки изображения на C++

99
21 апреля 2022, 12:00

Пишу программу, которая сглаживает изображения от шума вида соль-перец. В программе усредняющий фильтр, медианный и Гауссовский. Начал с усредняющего. Идея такова: Берем изображение, проходимся по нему окном размера kernel*kernel, усредняем все значения, которые находятся под окном, и записываем полученное среднее в новый массив. Краевые случаи не обрабатываем. Моя программа вроде как работает, но изображение становится очень темным. Скажите, пожалуйста, что я делаю не так?

Image blur(Image img, int kernel) {
    Image result;
    result.cols = img.cols - kernel + 1;;
    result.rows = img.rows - kernel + 1;;
    result.data = new char * [result.rows];
    for (size_t i = 0; i < result.rows; ++i) {
        result.data[i] = new char[result.cols];
    }
    for (size_t y = 0; y < result.rows; y++) {
        for (size_t x = 0; x < result.cols; x++) {
            int u = 0;
            for (int h = y; h < y + kernel; h++) {
                for (int w = x; w < x + kernel; w++) {
                    result.data[y][x] += (img.data[h][w]) / ((double)kernel*kernel);
                }
            }
        }
    }
    return result;
}

Где Image - это такая структура

struct Image {
    char** data = nullptr;
    size_t rows = 0;
    size_t cols = 0;
    size_t maxPixelValue = 255;
};

Изображение подается в формате .pgm (интервал значений от 0 до 255).

Answer 1

Постоянное отбрасывание остатка деления при накоплении результата result.data[y][x] += (img.data[h][w]) / ((double)kernel*kernel); явно будет приводить к резкому уменьшению итогового значения при росте kernel. Следует сначала все суммировать, а только потом поделить, причем избегая преобразований в / из числа с плавающей точкой.

Еще значения явно должны быть беззнаковыми char (::std::uint8_t).

READ ALSO
Перегрузка операнда ++

Перегрузка операнда ++

Необходимо перегрузить операцию ++ как движение по спискуВ чём ошибка?

115
почувствовать разницу inline и не inline метода

почувствовать разницу inline и не inline метода

подскажите, а как мне изменить тела конструкторов классов A и B, чтобы почувствовать разницу по производительности inline и не inline функций ??? или...

114
перегрузка оператор() через оператор[][] на c++ [дубликат]

перегрузка оператор() через оператор[][] на c++ [дубликат]

нужно так чтобы data[5][5] код выводил как data(5,5) и как результат выдавал произведение ixj, те

108