首页 > 解决方案 > 带水平线的透明验证码图像

问题描述

在此处输入图像描述

在此处输入图像描述

def resolve(img_path):
    image = Image.open(img_path)
    new_image = Image.new("RGBA", image.size, "WHITE")  # Create a white rgba background
    new_image.paste(image, (0, 0), image)  # Paste the image on the background.
    new_image.convert('RGB').save(img_path, "JPEG")  # Save as JPEG
    enhancedImage = enhance(img_path)
    return pytesseract.image_to_string(img_path)

def enhance(img_path):
    image1 = cv2.imread(img_path)
    #print(image1)
    img = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    ret, thresh1 = cv2.threshold(img, 180, 255, cv2.THRESH_BINARY_INV)
    #thresh = 50
    #im_bw = cv2.threshold(thresh3, thresh, 255, cv2.THRESH_BINARY)[1]
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 2))
    erosion = cv2.erode(thresh1, kernel, iterations = 1)
    return erosion

我正在尝试解决上述图像的验证码。尝试将透明 bg 转换为白色,然后增强图像,但结果不正确。

标签: pythonopencvtesseractpython-tesseract

解决方案


让我从您的代码的潜在问题开始

def enhance(img_path):
    image1 = cv2.imread(img_path)

现在,如果您阅读它,imread结果将是:

在此处输入图像描述

您无法pytesseract从输出图像中读取它。

这是此答案中所述的一个已知问题:cv2 imread transparent gone

如答案中所述:

在透明图像后面放一张白色图像,这样您就可以解决问题。

我们将应用相同的技术,现在结果将是:

在此处输入图像描述

至于第二个图像结果将是:

在此处输入图像描述

我们将执行以下步骤以有效地从输出图像中读取:

    1. 调整图像大小
    1. 应用自适应阈值

对于第一张图片,结果将是:

在此处输入图像描述

对于第二张图像,结果将是:

在此处输入图像描述

现在,当您pytesseract使用 mode 6 (modes)阅读它时,结果将是:

3daab
b42yb

代码:


import cv2
from PIL import Image
from pytesseract import image_to_string


def save_transparent_image(image_path, save_name):
    image = Image.open(image_path).convert("RGBA")
    canvas = Image.new(mode='RGBA',
                       size=image.size, color=(255, 255, 255, 255))
    canvas.paste(image, mask=image)
    canvas.save(save_name, format="PNG")


img_lst = ["o3upS.png", "kGpYk.png"]

for i, img_name in enumerate(img_lst):
    save_image = "captcha" + str(i) + ".png"
    save_transparent_image(img_name, save_image)

    # Step 1: Resize the image
    img = cv2.imread(save_image)
    (h, w) = img.shape[:2]
    img = cv2.resize(img, (w*2, h*2))

    # Step 2: Apply adaptive-threshold
    gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
                                cv2.THRESH_BINARY, 33, 79)

    # Step 3: Read the threshold image
    txt = image_to_string(thr, config="--psm 6")
    txt = txt.split("\n")[0]
    print(txt)

问题此代码是否适用于其他验证码?

不,不会的。除非验证码与给定示例相似。您需要更改adaptive-threshold'sblock-sizeC参数,看看它是否有效。


推荐阅读