2011-01-08 66 views
12

我通常的100%对比度调整方法和一些调整亮度以调整截止点的方法通常可以很好地清理小子电路的照片或E & R.SE上发表的公式,但有时候它并不是那么棒,像这样的图像:我应该使用哪些处理步骤来清理线条图的照片?

alt text

什么其他的方法除了对比度(或代替),我可以用它来给我一个更稳定的输出?我期待着一个相当普遍的答案,但我可能会使用ImageMagick和/或PIL(Python)将它实现在一个脚本中(我可以将文件转储到其中),所以如果你有任何特定的东西,将受到欢迎。

理想情况下,一个更好的源图像会很好,但我偶尔会在其他人的图像上使用它来添加一些波兰语。

+1

怎么样的颜色?我对图像处理并不熟悉,但似乎如果您删除了一定范围内的蓝色,网格将被删除。 – Mehrdad 2011-01-08 03:45:56

回答

15

第一步是在考虑到白平衡问题的同时均衡图像中的照明差异。这里的理论是,有限区域内最明亮的图像部分代表白色。通过事先模糊图像,我们消除了图像中噪声的影响。

from PIL import Image 
from PIL import ImageFilter 
im = Image.open(r'c:\temp\temp.png') 
white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(15)) 

alt text 下一步是从RGB输入创建的灰度图像。通过缩放到白点我们纠正白平衡问题。通过取R,G,B的最大值,我们不再强调任何不是纯灰色的颜色,例如网格的蓝线。这里介绍的第一行代码是虚拟的,用于创建正确大小和格式的图像。

grey = im.convert('L') 
width,height = im.size 
impix = im.load() 
whitepix = white.load() 
greypix = grey.load() 
for y in range(height): 
    for x in range(width): 
     greypix[x,y] = min(255, max(255 * impix[x,y][0]/whitepix[x,y][0], 255 * impix[x,y][2]/whitepix[x,y][3], 255 * impix[x,y][4]/whitepix[x,y][5])) 

这些操作的结果是具有大多一致的值,并且可以通过简单的阈值被转换成黑白图像。 alt text


编辑:很高兴看到一个小的竞争。 nikie已经提出了非常类似的方法,使用减法而不是缩放来消除白电平的变化。我的方法增加了照明不足的地区的对比度,而nikie的方法则不会 - 您选择哪种方法将取决于您希望保留的照明不足区域是否有信息。

我试图重现这种做法导致了这一点:

for y in range(height): 
    for x in range(width): 
     greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0], 255 + impix[x,y][7] - whitepix[x,y][8], 255 + impix[x,y][9] - whitepix[x,y][10])) 

alt text

我对技术的组合合作,提供一个更好的结果,但它尚未完全就绪。

+0

只是来自“竞争”的评论:您的建议和我的主要区别在于,您使用了一个(高斯?)模糊滤镜,然后是最大滤镜(=扩展)。矿山使用形态开放,大规模梯度几乎不变。问题是,PIL不包含形态过滤器(或者我没有找到它们)。 – Niki 2011-01-10 15:53:03

3

detecting edges怎么样?这应该拿起线条图。

这里的Sobel边缘检测的图像上的结果:

alt text

如果再阈值图像(使用经验确定的阈值,或者Ohtsu method),可以清理使用morphological operations图像(如扩张和侵蚀)。这将帮助你摆脱破碎/双重线。

正如Lambert指出的那样,如果您不希望结果中出现网格线,您可以使用蓝色通道预处理图像以摆脱网格线。

如果您在对图像进行图像处理之前均匀地照亮页面(或者只是使用扫描仪),那么您也将获得更好的效果,因此您不必担心全局与本地阈值之间的差异。

15

去除不同背景照明的一种常见方法是从图像中计算出“白色图像”,图像为opening

在此示例八度代码,我使用的图像的蓝色通道,因为在背景中的线是在该信道(EDITED至少突出:使用圆形结构元素产生更少的视觉伪像不是一个简单的箱):

src = imread('lines.png'); 
blue = src(:,:,3); 
mask = fspecial("disk",10); 
opened = imerode(imdilate(blue,mask),mask); 

结果:

background_subtracted = opened-blue; 
012: opened

然后从源图像中减去该

background_subtracted (对比度增强版)

最后,我只是用二值化固定阈值的图像:

binary = background_subtracted < 35; 

binary

相关问题