0
votes

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.

1

1 Answers

0
votes

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!