Search code examples
c++imageimage-processingsmoothingnoise-reduction

C++ Image Processing: Uniform Smoothing Operation Makes Image Darker


I'm trying to reduce noise in an image by creating a 2D uniform smoothing algorithm in C++. The function I'm using for each pixel computes the average value of neighboring pixels within a square odd window and uses that as the new value.

Whenever I run the code, however, the pixels in the new image become darker (a pixel value of 255=white, and 0=black). Here is the function for obtaining the new pixel value:

int utility::windowAverage (image &src, int x, int y, int window_size)
{
    int sum = 0;
    int avg;
    for(int i = x-(window_size/2); i < x+(window_size/2);++i)
    {
        for(int j = y-(window_size/2); j < y+(window_size/2);++j)
        {
            sum += src.getPixel(i,j);
        }
    }

    avg = sum/(window_size*window_size);
    return avg;
}

The parameter image &src is the source image, and the function src.getPixel(i,j) returns an integer from 0 to 255 representing the brightness of the pixel at the specified coordinates (i,j).

I am running the code over gray-level images of the .pgm format.

How can I smooth the image while maintaining the same brightness?


Solution

  • The problem is that you are not actually adding the pixels in a window with the dimension of windows_size*windows_size, but you are missing the last pixel in each dimension when computing sum.

    You can fix this by using <=instead of <in both of your for loops.


    Example of what is going wrong for window_size = 3 and x=0 and y=0:

    The integer division by 2 in your for loops is floored, which means that your loops would become for (int i=-1; i < 1; i++). This obviously only loops over the (two) pixles -1 and 0 in the given direction, but you still divide by the full window_size of 3, which makes the image darker (in this case by one third if it has constant color values).