简体   繁体   中英

(c++)(visual studio) Applying Gaussian Blur Filter to Grayscale Image From RGB

I converted a RGB picture to grayscale. Now I am trying to apply the Gaussian blur filter to this grayscale image. This is how i originally access the image:

pDoc = GetDocument();

int iBitPerPixel = pDoc->_bmp->bitsperpixel;    // used to see if grayscale(8 bits) or RGB (24 bits)
int iWidth = pDoc->_bmp->width;
int iHeight = pDoc->_bmp->height;
BYTE *pImg = pDoc->_bmp->point;     // pointer used to point at pixels in the image
int Wp = iWidth;
const int area = iWidth * iHeight;

This is the code I used to convert my RGB image into grayscale:

double r;           // red pixel value
double g;           // green pixel value
double b;           // blue pixel value
int gray;           // gray pixel value

// convert RGB values to grayscale at each pixel, then put in grayscale array
    for (int i = 0; i < iHeight; i++)
        for (int j = 0; j < iWidth; j++)
        {
            r = pImg[i*iWidth * 3 + j * 3 + 2];
            g = pImg[i*iWidth * 3 + j * 3 + 1];
            b = pImg[i*Wp + j * 3];

            r = static_cast<double>(r) * 0.299;
            g = static_cast<double>(g) * 0.587;
            b = static_cast<double>(b) * 0.114;

            gray = std::round(r + g + b);

            pImg[i*iWidth * 3 + j * 3 + 2] = gray;
            pImg[i*iWidth * 3 + j * 3 + 1] = gray;
            pImg[i*Wp + j * 3] = gray;

        }
}

And then here is where I attempt to apply the Gaussian blur filter:

// gaussian filter kernel
float gauss[3][3] = { {1, 2, 1},
{2, 4, 2},
{1, 2, 1} };

int convHeight;     // height value of convolution filter, gaussian in this case
int convWidth;      // width value of convolution filter, gaussian in this case


//////gaussian blur/////////
for (int i = 0; i < iHeight; i++) {
    for (int j = 0; j < iWidth; j++) {
        gaussPixel = 0;
        for (int x = 0; x < convHeight; x++) {
            for (int y = 0; y < convWidth; y++) {
                //gaussPixel += OldImage[x - convWidth / 2 + i, y - convHeight / 2 + j] * gauss[i, j];
            }
        }
        //NewImage[x, y] = gaussPixel;
    }
}

Some of my issues are as follows: 1) I am unsure how to make a condition for when one of the Gaussian blur kernels is looking at a spot that is off the image and is therefore not looking at a pixel and 2) I am getting an error from Visual Studio saying "Access violation reading location 0x...." which I assume is related to problem 1. Also I don't know if the fact that I changed the image from RGB to grayscale makes any difference in the way I read and write pixel values on the grayscale image.

Any and all help is greatly appreciated.

You don't have to check if you violate the image/array boundaries.

You know how large your image and your kernel are so all you have to do is to choose valid indices. If your image is 200 pixels wide you should not try to index x-coordinates < 0 or > 199.

This is a common problem in image-processing. Usually you have two options. Assuming we have a 5x5 kernel:

  1. you exclude a 2 pixel wide margin of your input image from the operation. then your kernel will always overlap valid pixels.
  2. you extend your input image by an artificial 2 pixel wide margin

Depending on the kind of filter and your application you may choose from different ways to create that margin. constant values, mirrored values, various extrapolations,...

I haven't looked into your calculations too much but you can always find examples for Gaussian implementations online which you can refer to.

I'd also encourage you to not just write a gaussian filter. Implement a convolution which you then can use with any Gaussian kernel or others.

Also keep in mind that the Gaussian filter is separable!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM