去噪验证码的条纹

3 投票
3 回答
1690 浏览
提问于 2025-04-18 10:11

我正在处理一种带有噪声条纹的验证码。这些条纹是随机方向的,而且都是直的。数字和条纹的颜色也是完全随机的。

enter image description here enter image description here enter image description here

下面的代码可以借助 tesseract 来识别一些验证码中的数字,具体可以参考这个链接:识别简单数字

from pytesser.pytesser import *
from PIL import Image, ImageFilter, ImageEnhance

im = Image.open("test.tiff")
im = im.filter(ImageFilter.MedianFilter()) # blur the image, the stripes will be erased
im = ImageEnhance.Contrast(im).enhance(2)  # increase the contrast (to make image clear?)
im = im.convert('1')                       # convert to black-white image
text = image_to_string(im)
print "text={}".format(text)

去除条纹的方法是先模糊图像,然后再锐化它。 在大多数情况下,识别的准确率是100%,但我在想是否有其他方法可以去除条纹,而不模糊数字。

任何建议都非常感谢。

3 个回答

1

在图像处理领域,有一类数学问题叫做“修复”。

你需要先得到一些条纹的遮罩,才能进行后续的操作。

这里有我整理的一些文章:http://dpaste.com/0CZ25FT。里面有很多现代的研究资料。

在OpenCV这个库里,有几个算法可以用:“Navier-Stokes”和“Telea”,不过它们在处理大面积修复时效果不太好。

你也可以在SciKit找到一些关于修复的参考资料,但那里的算法还没有完全实现。

另外,如果条纹的宽度始终是1个像素,可以通过扩张和腐蚀的方法轻松去掉。想了解更多,可以查阅Woods和Gonzalez的《数字图像处理》一书。

1

第二个例子很简单:扫描边缘,找出条纹的颜色,然后把这个颜色变成白色。(这些彩色线条并不是一个很强的验证码特征。)

第一个和第三个例子就比较复杂了,因为这些条纹的颜色和某些字符是一样的。你可以通过只去掉周围邻居少的条纹颜色的像素来解决这个问题。更好的方法是分析图像的轮廓,找出条纹的方向,并看看哪些周围的像素组合对应于条纹像素。

从技术上讲,你需要进行一种叫做“腐蚀”的操作,使用合适的形状作为结构元素。

3

为什么不试试利用这些条纹的宽度呢?我猜它们最多只有5像素。那么可以尝试做一些类似下面的伪代码:

  1. 把你的图片转换成一个 numpy 数组。
  2. 对于 方向 来说,可以是 上、下、左、右
    1. 创建一个新的 numpy 数组,向 方向 移动5像素,并裁剪掉边缘。
    2. 把新数组和旧数组进行“与”运算。
    3. 检查左下角。如果是白色的,那就完成了,你的图片已经去噪了。如果不是,就试试下一个方向。

考虑到数字的宽度比条纹要厚,我猜去掉条纹的效果会比“与”运算带来的失真要好。

撰写回答