首页 > 解决方案 > 使用任何库从 python 中的验证码中读取所有字符

问题描述

我想将验证码字符作为一个字符串读取。

我要解析的验证码是特定模式。示例图像如下:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

以上所有验证码图像背景都是相同的,依此类推。每次只有字符在其位置上随机排列(即字符在特定方向上不可用),但似乎所有字符长度都是相同的。

我尝试使用pytesseract python 库从这些图像中读取文本。此外,我尝试了此处可用的示例,但这些都不适合我。

这个 SO 链接中,我找到了一种解决方案,它是市场上正确/正确的答案,但它仅适用于数字验证码。

此外,许多人建议首先我们应该从图像中移除噪声/模糊背景,然后我们应该处理图像,但这对我来说是完全不知道的事情。

我尝试如下:

from PIL import Image, ImageEnhance, ImageFilter
import pytesseract

img = Image.open("test.png")
imagetext = pytesseract.image_to_string(img)
print(imagetext) 

谁能指出我的方向?

标签: pythonimageimage-processingocrcaptcha

解决方案


由于验证码中使用的符号数量有限(拉丁字母 + 数字)并且符号形状始终保持不变,您可以创建如下符号库:

在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述在此处输入图像描述

您需要用适当的名称命名每个图像,例如:“F.png”并放入“lib”文件夹。然后针对您的验证码运行以下脚本:

import cv2
import glob
import numpy
import ntpath
from PIL import Image

IMAGES = ['S3RZX.png', 'HF482.png', 'YMMR9.png']
symbols = glob.glob('lib/*.png')


def guess_captcha(image):
    image = Image.open(image)
    pixels = image.load()
    size = image.size

    # Cleanup background noises from captcha
    for x in range(size[0]):
        for y in range(size[1]):
            if pixels[x, y][0] < 120:
                pixels[x, y] = (0, 0, 0)
            else:
                pixels[x, y] = (255, 255, 255)

    # Search symbols in captcha
    image = numpy.array(image)
    result = []
    for symbol in symbols:
        img_symbol = cv2.imread(symbol)
        match = cv2.matchTemplate(img_symbol, image, cv2.TM_CCOEFF_NORMED)
        if len(match):
            _, quality, _, location = cv2.minMaxLoc(match)
            if quality > 0.8:
                result.append({'x': location[0], 'symbol': ntpath.basename(symbol).replace('.png', '')})
    result = sorted(result, key=lambda k: k['x'])
    return ''.join([x['symbol'] for x in result])


for img in IMAGES:
    print('{} -> {}'.format(img, guess_captcha(img)))

我最后得到了什么:

S3RZX.png -> S3RZX
HF482.png -> HF482
YMMR9.png -> YR9

前两个验证码正确解决。由于“M”符号覆盖,最后一个验证码解决不正确。叠加问题真的很难解决,所以最好跳过这样的验证码。


推荐阅读