aplying时的小颜色缺陷意味着对图像进行过滤

时间:2016-07-05 13:47:38

标签: c++ image-processing rgb mean

我一直在努力做一个程序,对图像应用均值滤镜,我认为我接近正确,但图像中仍有小缺陷。例如:

原创赛车:http://s72.photobucket.com/user/john_smith140/media/gp4_zpstafhejk5.jpg.html?filters[user]=139318132&filters[recent]=1&sort=1&o=2

原始三角形:http://s72.photobucket.com/user/john_smith140/media/input_zpsz2cfhrc7.jpeg.html?filters[user]=139318132&filters[recent]=1&sort=1&o=3

修改赛车:http://s72.photobucket.com/user/john_smith140/media/racing_zpsmzmawjml.jpeg.html?filters[user]=139318132&filters[recent]=1&sort=1&o=0

修改过的三角形:http://s72.photobucket.com/user/john_smith140/media/triangles_zpsaretjfid.jpeg.html?filters[user]=139318132&filters[recent]=1&sort=1&o=1

黑色背景白点,原文:http://s72.photobucket.com/user/john_smith140/media/black%20background%20white%20dots_zpsuofaagnl.jpg.html?sort=3&o=2

黑色背景白点,相同数组:http://s72.photobucket.com/user/john_smith140/media/one%20array_zpswteno2eb.jpg.html?sort=3&o=1

黑色背景白点,不同数组:http://s72.photobucket.com/user/john_smith140/media/two%20array_zpskbyjg97o.jpg.html?sort=3&o=0

我可以考虑两个导致这些缺陷的原因。一个算法本身和另一个在将char转换为float然后再次浮动到char的过程中。

Char to float conversion是必要的,因为ifstream的read函数读取char然后我需要乘以1/9,所以它需要是浮点数。然后转换回char,这样write函数就可以将其写回来。

关于算法的一些解释。我开始从第二行的第二个像素计算颜色值,然后继续计算直到第二个最后一行的第二个最后一个像素。那是因为我使用的是3x3的内核,这样我就不会超出图像的限制(以及我存储它的char数组)。对于1024x768的图像,它的大小为1024x768 * 3(3种颜色分量)。所以它从位置开始:bitsPerPixel * image_width + bitsPerPixel或3 * 1024 + 3 = 4099,2°行的2°像素。然后它将计算平均值,直到2°最后一行的2°最后一个像素应该是: imageSize - row_size - bitsPerPixel或(1024 * 768-3) - 1024 * 3 - 3。 在该区间中,它将计算char数组中每个位置的值,这意味着像素的每个颜色通道的值将由周围像素的颜色通道计算。 这是代码:

int size2 = bpp*width;
float a1_9 = (1.0f/9.0f);
float tmp;
for (int i=size2+bpp; i<size-size2-bpp; i++) {
tmp = a1_9 * ((float) image [i-size2-bpp] + (float) image [i-size2] + (float) image [i-size2+bpp] + (float) image [i-bpp] + (float) image [i] + (float) image [i+bpp] + (float)image [i+size2-bpp] + (float) image [i+size2] + (float) image [i+size2+bpp]);
    image [i] = char (tmp);
    float temp = (float) image [i];
}

我打印了赛车屏幕截图的一次互动的价值,对应于百万位置的价值并得到了这个:

Image values are: -56 -57 -57 9 -43 -41 108 108 109 
tmp it is: 8.88889
temp it is: 8

乍一看这些价值似乎是正确的(手头上的平均值),所以我对错误的原因并不了解。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

2关于你的算法的想法:

1。)您正在使用RGB色彩空间?那么为什么你的Image值为负?此外,您不必转换为浮动。只需将整数值加起来并除以9.这要快得多,最后你将它转换回char,所以它应该是相同的结果。

2。)您在每个迭代步骤中覆盖您的图像,这意味着在过滤器模式中:

-------
|1|2|3|
-------
|4|5|6|
-------
|7|8|9|
-------

值1,2,3和4已经过平滑处理,5是从5个非平滑像素和4个平滑像素计算得出的。 我建议创建一个新的空白图像并将结果(temp)存储在新图像中,同时从原始图像中读取 - 即不要尝试使用输出图像处理“就地”与输入图像相同。

答案 1 :(得分:0)

我在BGR图像格式上实现了3x3模糊滤镜。

重要告示:

  • 以BRG(或RGB)格式过滤和图像时,必须单独过滤每个颜色通道。
  • 当执行过滤器(使用卷积)时,重要的是来使用&#34;到位&#34;计算 - 避免源被目标元素覆盖。
  • 乘以(1/9)比除以9更有效。
  • 在整数转换之前添加0.5可用于舍入正值。
  • 通过扩展,缩放和移位执行的(1/9)缩放的定点实现。示例:avg =(sum * scale + rounding)&gt;&gt; 15; [当比例=(1/9)* 2 ^ 15]。

我假设内存中的像素顺序是b,g,r,b,g,r ...(b在字节0中)。

以BRG(或RGB)格式过滤图像时,必须单独过滤每个颜色通道!

分色的插图:

bgrbgrbgr
bgrbgrbgr
bgrbgrbgr

分开:

bbb ggg rrr
bbb ggg rrr
bbb ggg rrr

模糊滤镜内核是:
1 / 9,1 / 9,1 / 9
1 / 9,1 / 9,1 / 9
1 / 9,1 / 9,1 / 9
如上所述,过滤器应分别应用于蓝色,绿色和红色。

你可以将每个3x3像素相加并将结果除以9(或者更好地乘以1/9)。
我使用固定点实现乘以1/9,而不是转换为浮点数 定点实现用于提高性能(这里不太重要,因为代码没有优化) 我想要展示这项技术......

我使用了一些代码重复,以强调RGB颜色分离 我还处理了图像边界(使用对称镜像)。

这是我的代码:

CheckListItemArray

输入图像:
enter image description here

输出图像:
enter image description here