0

这是多么痛苦啊。基本上,我要做的就是在图像上实现一个简单的模糊滤镜。我正在使用相同的图像,它是 24 位位图 (Lena512.bmp)。现在的问题是,我编写的 Java 实现按预期工作。然而,C 实现,而不是模糊我想要的区域,实际上使该区域变暗并且看起来很奇怪。我不太确定这是否与 RGB (BGR) 转换有关。我能够将特定像素转换为颜色并读取相同的颜色。

我想学习有关图像处理的知识,而不是依赖 OpenCV 库来解决所有问题,而只是从我的网络摄像头和磁盘中抓取图片。

这是我的有效 Java 实现。Img 包含 24 位 lena512.bmp。

private void applyFilter()
{       
    //Apply the filter 3 times
    for (int n = 0; n < 3; n++) {
        for (int y=100; y < 300; y++) {
            for (int x=100; x<300; x++) {
                int r = 0,g = 0,b = 0;
                    for (int j = -1; j <= 1; j++) {
                        for (int k=-1; k<=1; k++) {
                            int pixel = img.getRGB(x + k, y + j);
                            r += (new Color(pixel).getRed());
                            g += (new Color(pixel).getGreen());
                            b += (new Color(pixel).getBlue());
                        }
                    }
                    r = r / 9; //Assume a 3x3 matrix, to average out.
                    g = g / 9;
                    b = b / 9;
                    img.setRGB(x, y, new Color(r,g,b).getRGB());
                }
            }
        }
}

我的 C 实现看起来像这样。Img 包含 24 位 lena512.bmp。

void applyAverage(IplImage *img)
{
    int x,y;
    int nx, ny;

    for ( y = 100; y < 400; y++) {
            for ( x = 100; x < 400; x++) {
                    unsigned char r,g,b;
                    for ( ny = -1; ny <= 1; ny++) {
                            for ( nx = -1; nx <= 1; nx++) {
                                    getPixel(img,x + nx,y + ny,&r, &g, &b);
                                    r += r;
                                    g += g;
                                    b += b;
                            }
                    }
                    r = r / 9;
                    g = g / 9;
                    b = b / 9;
                    setPixel(img, x, y, &r, &g, &b);
            }
    }
}

在 C 实现的 main 方法中,我按如下方式加载图像:

IplImage *frame = cvLoadImage("lena512.bmp",1);

我的 getPixel 和 getPixel 工作,因为我能够设置和获取这些(我知道 RGB ---> BGR 字节排序,这不是问题)。显然,我在这里遗漏了一些东西。

谢谢人们。

我已经链接(我的代表太低)问题的图片。左边是java实现,右边是OpenCV。

http://i176.photobucket.com/albums/w189/Phil128/Problem_zps431a4a4f.png

4

2 回答 2

2

仔细查看应该累积强度值的这段代码:

getPixel(img,x + nx,y + ny,&r, &g, &b);
r += r;
...

getPixel在每次迭代中不断覆盖累加器变量r, 。这意味着,在您查询过滤器区域的最后一个像素之后。, , 并且只保存最后一个像素的值。因此最终意味着每个过滤像素的强度最终将大约是原始像素右下角相邻像素强度的九分之二。因此该区域变得非常黑暗。gbrgbr += rr = r / 9

尝试使用单独的变量来接收过滤区域中每个像素的强度值,例如curr_rcurr_gcurr_bin:

int r = 0, g = 0, b = 0;
for ( ny = -1; ny <= 1; ny ++) {
    for ( nx = -1; nx <= 1; n x++) {
        int curr_r, curr_g, curr_b; 
        getPixel(img, x + nx, y + ny, & curr_r, & curr_g, &curr_b);
        r += curr_r; 
        g += curr_g;
        b += curr_b;
    }
}
r = r / 9;
g = g / 9;
b = b / 9;

在这里,例如,getPixel将强度值放入curr_r中,然后curr_r添加到累加变量r中。

另一件事。您正在传递、 和to的地址r,如。这可能是正确的方法,但我更希望接受. 值得仔细检查该函数的声明。gbsetPixelsetPixel(img, x, y, & r, & g, & b);setPixelsetPixel(img, x, y, r, g, b);

于 2013-10-26T00:53:26.850 回答
0

排序。傻我。我使用的是无符号字符,而不是整数。当我缺乏睡眠时会发生什么:-D。

于 2013-10-26T09:05:17.197 回答