简单的验证码解决
Simple Captcha Solving
我正在尝试使用 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 获得了更好的整体检测精度。
这是新生成的图像:
我采用了更直接的方法来过滤 pdf 文档中的墨迹。我不会分享整个事情,因为它有很多代码,但这是我采用的一般策略:
- 使用 Python Pillow 库获取图像对象,您可以在其中直接操作像素。
- 将图像二值化。
- 找出所有连接的像素以及每组连接的像素中有多少像素。您可以使用扫雷算法来执行此操作。哪个好找。
- 设置所有合法字母应具有的像素阈值。这将取决于您的图像分辨率。
- 用白色像素替换低于阈值的组中的所有黑色像素。
- 转换回图像。
您的最终输出图像太模糊了。要提高 pytesseract 的性能,您需要对其进行改进。
锐化不像模糊那么容易,但存在一些代码片段/教程(例如 http://datahacker.rs/004-how-to-smooth-and-sharpen-an-image-in-opencv/)。
与其链接模糊,不如使用高斯模糊或中值模糊模糊一次,试验参数以获得您需要的模糊量,或许可以尝试一种方法又一种方法,但没有理由将相同方法的模糊链接起来。
python 中有一个检测字符的 OCR 示例。保存多张图像并应用过滤器并训练 SVM 算法。这可能对你有帮助。我确实用很少的图像训练了一个算法,但结果是可以接受的。检查此 link。
祝你好运
我知道 post 有点旧,但我建议您试试我不久前开发的 library。如果您有一组带标签的验证码,该服务将适合您。看一看:https://github.com/punkerpunker/captcha_solver
README 中有一个您可能感兴趣的“基于外部数据训练模型”部分。
我正在尝试使用 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 获得了更好的整体检测精度。
这是新生成的图像:
我采用了更直接的方法来过滤 pdf 文档中的墨迹。我不会分享整个事情,因为它有很多代码,但这是我采用的一般策略:
- 使用 Python Pillow 库获取图像对象,您可以在其中直接操作像素。
- 将图像二值化。
- 找出所有连接的像素以及每组连接的像素中有多少像素。您可以使用扫雷算法来执行此操作。哪个好找。
- 设置所有合法字母应具有的像素阈值。这将取决于您的图像分辨率。
- 用白色像素替换低于阈值的组中的所有黑色像素。
- 转换回图像。
您的最终输出图像太模糊了。要提高 pytesseract 的性能,您需要对其进行改进。
锐化不像模糊那么容易,但存在一些代码片段/教程(例如 http://datahacker.rs/004-how-to-smooth-and-sharpen-an-image-in-opencv/)。
与其链接模糊,不如使用高斯模糊或中值模糊模糊一次,试验参数以获得您需要的模糊量,或许可以尝试一种方法又一种方法,但没有理由将相同方法的模糊链接起来。
python 中有一个检测字符的 OCR 示例。保存多张图像并应用过滤器并训练 SVM 算法。这可能对你有帮助。我确实用很少的图像训练了一个算法,但结果是可以接受的。检查此 link。 祝你好运
我知道 post 有点旧,但我建议您试试我不久前开发的 library。如果您有一组带标签的验证码,该服务将适合您。看一看:https://github.com/punkerpunker/captcha_solver
README 中有一个您可能感兴趣的“基于外部数据训练模型”部分。