简体   繁体   English

(c ++)(Visual Studio)将高斯模糊滤镜应用于RGB的灰度图像

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

I converted a RGB picture to grayscale. 我将RGB图片转换为灰度。 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: 这是我用来将RGB图像转换为灰度的代码:

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. 我的一些问题如下:1)我不确定如何为其中一个高斯模糊内核看着一个偏离图像的点,因此不看着像素的情况作条件; 2)我正在获取我认为来自Visual Studio的错误说“访问冲突读取位置0x ....”与问题1有关。同样,我也不知道我将图像从RGB更改为灰度的事实是否在方式上有所不同我在灰度图像上读写像素值。

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. 如果图像的宽度为200像素,则不应尝试索引<0或> 199的x坐标。

This is a common problem in image-processing. 这是图像处理中的常见问题。 Usually you have two options. 通常,您有两个选择。 Assuming we have a 5x5 kernel: 假设我们有一个5x5内核:

  1. you exclude a 2 pixel wide margin of your input image from the operation. 您从操作中排除了输入图像2像素宽的边距。 then your kernel will always overlap valid pixels. 那么您的内核将始终与有效像素重叠。
  2. you extend your input image by an artificial 2 pixel wide margin 您将输入图像扩展到人为的2像素宽边距

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! 还请记住,高斯滤波器是可分离的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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