我正在尝试使用 python 和 PyQT5 实现二进制图像过滤器(以获取单色二进制图像),并且要检索新的像素颜色,我使用以下方法:
def _new_pixel_colors(self, x, y):
color = QColor(self.pixmap.pixel(x, y))
result = qRgb(0, 0, 0) if all(c < 127 for c in color.getRgb()[:3]) else qRgb(255, 255, 255)
return result
这可能是 RGB 图像二元滤波器 的正确样本吗?我的意思是,这是检查像素比 (127,127,127)
灰色更亮还是更暗的充分条件吗?
并且请不要使用 opencv、pillow 等提供任何解决方案。我只是问算法本身。
最佳答案
我至少会比较强度 i=R+G+B
...
对于像蒙版这样的ROI,您可以使用任何阈值技术(自适应阈值是最好的),但如果您得到的图像不是ROI mask 并且应该类似于原始图像的视觉特征然后我知道最好的转换是使用 Dithering .
BW 抖动背后的想法是将灰度转换为 BW 模式,同时保留阴影。结果通常很嘈杂,但保留了更多的视觉细节。这里简单的天真 C++ 抖动(抱歉不是 Python 编码器):
picture pic0,pic1;
// pic0 - source img
// pic1 - output img
int x,y,i;
color c;
// resize output to source image size clear with black
pic1=pic0; pic1.clear(0);
// dithering
i=0;
for (y=0;y<pic0.ys;y++)
for (x=0;x<pic0.xs;x++)
{
// get source pixel color (AARRGGBB)
c=pic0.p[y][x];
// add to leftovers
i+=WORD(c.db[picture::_r]); // _r,_g,_b are just constants 0,1,2
i+=WORD(c.db[picture::_g]);
i+=WORD(c.db[picture::_b]);
// threshold white intensity is 255+255+255=765
if (i>=384){ i-=765; c.dd=0x00FFFFFF; } else c.dd=0;
// copy to destination image
pic1.p[y][x]=c;
}
所以它与上面的链接相同,但只使用黑色和白色。 i
是要放置在图像上的累积强度。 xs,ys
是分辨率,c.db[]
是颜色 channel 访问。
如果我像这样将它应用到彩色图像上:
结果是这样的:
如您所见,保留了所有细节,但出现了嘈杂的图案……出于打印目的,有时会提高图像的分辨率以提高质量。如果您使用更好的模式(如 16x16 方 block 等)更改 naive 2 嵌套 for 循环,那么噪声将被保存在其源限制工件附近。还有一些使用伪随机模式的方法(将剩余的 i
放在随机位置的源像素附近)甚至更好......
但是对于 BW 抖动,即使是简单的方法也足够了,因为伪影只有一个像素大小。对于彩色抖动,伪影可能会产生几个像素大小的不需要的水平线图案(取决于使用的调色板不匹配,调色板越差,伪影越大...)
PS 只是为了与其他答案阈值输出进行比较,这是抖动的相同图像:
关于Python:如何在 RGB 图像上实现二值滤波器? (算法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53807459/