简单的验证码解决

Posted

技术标签:

【中文标题】简单的验证码解决【英文标题】:Simple Captcha Solving 【发布时间】:2020-11-07 16:10:21 【问题描述】:

我正在尝试使用 OpenCV 和 pytesseract 解决一些简单的验证码。一些验证码样本是:

我尝试用一​​些过滤器去除嘈杂的点:

import cv2
import numpy as np
import pytesseract

img = cv2.imread(image_path)
_, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
img = cv2.morphologyEx(img, cv2.MORPH_OPEN, np.ones((4, 4), np.uint8), iterations=1)
img = cv2.medianBlur(img, 3)
img = cv2.medianBlur(img, 3)
img = cv2.medianBlur(img, 3)
img = cv2.medianBlur(img, 3)
img = cv2.GaussianBlur(img, (5, 5), 0)
cv2.imwrite('res.png', img)
print(pytesseract.image_to_string('res.png'))

生成的转换图像是:

不幸的是,pytesseract 只能正确识别第一个验证码。还有其他更好的转换吗?

最终更新:

正如@Neil 所建议的,我尝试通过检测连接的像素来消除噪音。为了找到连接的像素,我找到了一个名为connectedComponentsWithStats 的函数,它检测连接的像素并为组(组件)分配一个标签。通过找到连接的组件并删除具有少量像素的组件,我设法使用 pytesseract 获得更好的整体检测精度。

以下是新生成的图像:

【问题讨论】:

验证码是 CLYBJ CZSLK GJZPJ WATID 成功了。太好了。 【参考方案1】:

我采用了一种更直接的方法来过滤 pdf 文档中的墨迹。我不会分享整个事情,因为它有很多代码,但这是我采用的一般策略:

    使用 Python Pillow 库获取可以直接操作像素的图像对象。 二值化图像。 查找所有连接像素以及每组连接像素中有多少像素。您可以使用扫雷算法来做到这一点。哪个很容易搜索。 设置所有合法字母都应具有的像素阈值。这取决于您的图像分辨率。 将低于阈值的组中的所有黑色像素替换为白色像素。 转换回图像。

【讨论】:

【参考方案2】:

您的最终输出图像太模糊。要提高 pytesseract 的性能,您需要对其进行锐化。

锐化不像模糊那么容易,但存在一些代码 sn-ps / 教程(例如http://datahacker.rs/004-how-to-smooth-and-sharpen-an-image-in-opencv/)。

与其链接模糊,不如使用高斯模糊或中值模糊一次模糊,尝试参数以获得所需的模糊量,也许尝试一种又一种方法,但没有理由链接相同方法的模糊。

【讨论】:

【参考方案3】:

python中有一个检测字符的OCR示例。保存多张图像并应用过滤器并训练 SVM 算法。这可能会帮助你。我确实用很少的图像训练了一个算法,但结果是可以接受的。检查此link。 祝你好运

【讨论】:

【参考方案4】:

我知道这篇文章有点老了,但我建议你试试我前段时间开发的这个。如果您有一组带标签的验证码,该服务将适合您。看一看:https://github.com/punkerpunker/captcha_solver

在 README 中,您可能会感兴趣的部分“根据外部数据训练模型”。

【讨论】:

以上是关于简单的验证码解决的主要内容,如果未能解决你的问题,请参考以下文章

Python中验证码识别的三种解决方案

浅谈JAVA验证码~

验证码对抗之路及现有验证机制介绍

验证码识别竞赛解决方案(97%)

Python爬虫过程中验证码识别的三种解决方案

litrpa众筹内网本地图片验证码识别组件