python - 通过复制 TesserCap 的斩波滤波器去除验证码图像的背景噪声

标签 python image-processing imagemagick python-imaging-library

我有一个看起来像这样的验证码图像:

使用名为 TesserCap 的实用程序来自 McAfee,我可以对图像应用“斩波”过滤器。 (在运行它之前,我确保图像中只有两种颜色,白色和黑色。)我对在文本框中使用值为 2 的过滤器的结果印象深刻。它准确地去除了大部分噪音但保留了主要文本,结果如​​下:

我想在我自己的一个脚本中实现类似的东西,所以我试图找出 TesserCap 使用的图像处理库。我找不到任何东西;事实证明它使用自己的代码来处理图像。然后我读了this whitepaper这确切地解释了程序是如何工作的。它给了我以下关于这个斩波滤波器的作用的描述:

If the contiguous number of pixels for given grayscale values are less than the number provided in the numeric box, the chopping filter replaces these sequences with 0 (black) or 255 (white) as per user choice. The CAPTCHA is analyzed in both horizontal and vertical directions and corresponding changes are made.

我不确定我是否理解它在做什么。我的脚本是用 Python 编写的,所以我尝试使用 PIL 来操纵像素,就像那句话所描述的那样。这听起来有点简单,但我失败了,可能是因为我真的不知道过滤器到底在做什么:

(这是由使用圆形图案的略有不同的验证码制成的。)

我还尝试看看是否可以使用 ImageMagick 的 convert.exe 轻松完成。他们的 -chop 选项完全不同。使用 -median 和一些 -morphology 命令有助于减少一些噪音,但出现了讨厌的点并且字母变得非常扭曲。这远不像用 TesserCap 做斩波滤波器那么简单。

所以,我的问题如下:如何在 Python 中实现 TesserCap 的斩波滤波器,是使用 PIL 还是 ImageMagick?该斩波滤波器比我尝试过的任何替代方案都要好得多,但我似乎无法复制它。我已经为此工作了几个小时,但还没有想出任何办法。

最佳答案

该算法主要检查一行中是否有多个目标像素(在本例中为非白色像素),如果像素数小于或等于截断因子,则更改这些像素。

例如,在示例像素行中,# 为黑色,- 为白色,应用 2 的截断因子将将 --#--###-##---#####---#-# 转换为 ------###---- ---#####--------。这是因为存在小于或等于2个像素的黑色像素序列,这些序列被白色替换。保留大于2个像素的连续序列。

这是在我的 Python 代码(下方)中对您帖子中的原始图像实现的 chop 算法的结果:

'Chopped' image

为了将此应用于整个图像,您只需在每一行和每一列上执行此算法。下面是完成此操作的 Python 代码:

import PIL.Image
import sys

# python chop.py [chop-factor] [in-file] [out-file]

chop = int(sys.argv[1])
image = PIL.Image.open(sys.argv[2]).convert('1')
width, height = image.size
data = image.load()

# Iterate through the rows.
for y in range(height):
    for x in range(width):

        # Make sure we're on a dark pixel.
        if data[x, y] > 128:
            continue

        # Keep a total of non-white contiguous pixels.
        total = 0

        # Check a sequence ranging from x to image.width.
        for c in range(x, width):

            # If the pixel is dark, add it to the total.
            if data[c, y] < 128:
                total += 1

            # If the pixel is light, stop the sequence.
            else:
                break

        # If the total is less than the chop, replace everything with white.
        if total <= chop:
            for c in range(total):
                data[x + c, y] = 255

        # Skip this sequence we just altered.
        x += total


# Iterate through the columns.
for x in range(width):
    for y in range(height):

        # Make sure we're on a dark pixel.
        if data[x, y] > 128:
            continue

        # Keep a total of non-white contiguous pixels.
        total = 0

        # Check a sequence ranging from y to image.height.
        for c in range(y, height):

            # If the pixel is dark, add it to the total.
            if data[x, c] < 128:
                total += 1

            # If the pixel is light, stop the sequence.
            else:
                break

        # If the total is less than the chop, replace everything with white.
        if total <= chop:
            for c in range(total):
                data[x, y + c] = 255

        # Skip this sequence we just altered.
        y += total

image.save(sys.argv[3])

关于python - 通过复制 TesserCap 的斩波滤波器去除验证码图像的背景噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11253899/

相关文章:

python-requests:是否可以绕过 HTTPS 以提高速度

python - 自定义 Django 管理站点

java - 凸起效应算法说明

c# - 使用 ImageMagick.NET 将 PDF 转换为图像 - 如何设置 DPI

python - 在 Model.get_by_id() 上出现 "Expected string, got None"错误

python - 无法实现用于解决密码的爬山算法

c++ - 在 C++ 中使用 OpenCV 查找每个 Blob 中的像素数

c# - 如何比较两幅图像并识别图像中的图案?

ruby-on-rails - Rails Paperclip 插件 - 调整大小的样式选项

pdf - Ghostscript灰度转换仍然包含颜色?