Результат заточения лапласиан - своего рода сероватый C ++ - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь реализовать лапласианский фильтр для повышения резкости изображения.но результат вроде серый, я не знаю, что пошло не так с моим кодом.

Вот моя работа до сих пор

     img = imread("moon.png", 0);
     Mat convoSharp() {

    //creating new image
    Mat res = img.clone();
    for (int y = 0; y < res.rows; y++) {
        for (int x = 0; x < res.cols; x++) {
            res.at<uchar>(y, x) = 0.0;
        }
    }

    //variable declaration
    //change -5 to -4 for original result.
    int filter[3][3] = { {0,1,0},{1,-4,1},{0,1,0} };
    //int filter[3][3] = { {-1,-2,-1},{0,0,0},{1,2,1} };
    int height = img.rows;
    int width = img.cols;
    int **temp = new int*[height];
    for (int i = 0; i < height; i++) {
        temp[i] = new int[width];
    }
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            temp[i][j] = 0;
        }
    }
    int filterHeight = 3;
    int filterWidth = 3;
    int newImageHeight = height - filterHeight + 1;
    int newImageWidth = width - filterWidth + 1;
    int i, j, h, w;

    //convolution
    for (i = 0; i < newImageHeight; i++) {
        for (j = 0; j < newImageWidth; j++) {
            for (h = i; h < i + filterHeight; h++) {
                for (w = j; w < j + filterWidth; w++) {
                    temp[i][j] += filter[h - i][w - j] * (int)img.at<uchar>(h, w);
                }
            }
        }
    }

    //find max and min
    int max = 0;
    int min = 100;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (temp[i][j] > max) {
                max = temp[i][j];
            }
            if (temp[i][j] < min) {
                min = temp[i][j];
            }
        }
    }

    //clamp 0 - 255
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            res.at<uchar>(i, j) = 0 + (temp[i][j] - min)*(255 - 0) / (max - min);
        }
    }

    //empty the temp array
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            temp[i][j] = 0;
        }
    }

    //img - res and store it in temp array
    for (int y = 0; y < res.rows; y++) {
        for (int x = 0; x < res.cols; x++) {
            //int a = (int)img.at<uchar>(y, x) - (int)res.at<uchar>(y, x);
            //cout << a << endl;
            temp[y][x] = (int)img.at<uchar>(y, x) - (int)res.at<uchar>(y, x);

        }
    }

    //find the new max and min
    max = 0;
    min = 100;
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (temp[i][j] > max) {
                max = temp[i][j];
            }
            if (temp[i][j] < min) {
                min = temp[i][j];
            }
        }
    }

    //clamp it back to 0-255
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            res.at<uchar>(i, j) = 0 + (temp[i][j] - min)*(255 - 0) / (max - min);
            temp[i][j] = (int)res.at<uchar>(i, j);
        }
    }



    return res;
}

А вот результат

Result

Как вы можете видеть в моем коде выше, я уже нормализую значение пикселя до 0-255.Я до сих пор не знаю, что здесь пошло не так.Может кто-нибудь здесь объяснить, почему это так?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Серая причина в том, что , как Макс предложил в своем ответе , вы масштабируете диапазон до 0-255, а не зажимаете (как подсказывают ваши комментарии в коде).

Однакоэто не все проблемы в вашем коде.Выходные данные оператора Лапласа содержат отрицательные значения.Вы хорошо храните их в int.Но затем вы масштабируете и копируете в char.Не делайте этого!

Вам нужно добавить результат Лапласа без изменений в ваше изображение.Таким образом, некоторые пиксели в вашем изображении станут темнее, а некоторые светлее.Это то, что заставляет края выглядеть более острыми.

Просто пропустите некоторые циклы в вашем коде и оставьте один, который делает temp = img - temp.В результате вы можете свободно масштабировать или фиксировать выходной диапазон и приводить к char.

. Для фиксации просто установите любые значения пикселей от 0 до 0, а любые от 255 до 255. Не вычисляйте min/ max и масштабируйте, как вы, потому что там вы уменьшаете контраст и создаете сероватый оттенок на вашем изображении.

Ваш последний вопрос довольно похож (хотя проблема в коде была другой), прочитайте myОтветьте здесь еще раз, он предлагает способ еще больше упростить ваш код, чтобы img-Laplace превратился в одну свертку.

0 голосов
/ 10 октября 2018

Проблема в том, что вы зажимаете и масштабируете изображение.Посмотрите на нижнюю левую границу луны: рядом с очень темными пикселями есть очень яркие пиксели, а затем, кроме ярких, есть несколько серых пикселей.Ваш фильтр повышения резкости будет действительно всплывать на этой яркой границе и увеличивать максимум.Точно так же черные пиксели будут уменьшены еще больше.

Затем вы определяете минимальное и максимальное значения и масштабируете все изображение.Это обязательно означает, что все изображение будет терять контраст при отображении в предыдущей серой шкале, поскольку ваш фильтр выводит значения пикселей выше 255 и ниже 0.

Присматривает границу луны на выходном изображении:

enter image description here

Есть черный ореол (новый 0) и яркий, острый край (новый 255). (Масштабирование изображения в браузере сделало его менее четким на этом скриншоте, посмотрите на исходный вывод). Все остальное было подавлено изменением масштаба, поэтому то, что было предыдущим черным (0), теперь стало темно-серым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...