首页 > 解决方案 > Laplacian Sharpening result is kinda greyish C++

问题描述

I am trying to implement laplacian filter for sharpening an image. but the result is kinda grey , I don't know what went wrong with my code.

Here's my work so far

     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;
}

And here's the result

Result

as you can see in my code above , i already normalize the pixel value to 0-255. i still don't know what went wrong here. Can anyone here explain why is that ?

标签: c++opencvimage-processing

解决方案


The problem is that you are clamping and rescaling the image. Look at the bottom left border of the moon: There are very bright pixels next to very dark pixels, and then some gray pixels right besides the bright ones. Your sharpening filter will really spike on that bright border and increase the maximum. Similarly, the black pixels will be reduced even further.

You then determine minimum and maximum and rescale the entire image. This necessarily means the entire image will lose contrast when displayed in the previous gray scale, because your filter outputted pixel values above 255 and below 0.

Looks closely at the border of the moon in the output image:

enter image description here

There is a black halo (the new 0) and a bright, sharp edge (the new 255). (The browser image scaling made it less crisp in this screenshot, look at your original output). Everything else was squashed by the rescaling, so what was previous black (0) is now dark gray.


推荐阅读