【问题标题】:can't recognize correctly license plate (Python, OpenCv, Tesseract)无法正确识别车牌(Python、OpenCv、Tesseract)
【发布时间】:2020-07-24 10:42:39
【问题描述】:

我正在尝试识别车牌,但出现错误,例如错误/未读取字符

这是每个步骤的可视化:

通过颜色阈值+变形关闭获得蒙版

过滤以绿色突出显示的车牌轮廓

将板轮廓粘贴到空白蒙版上

Tesseract OCR 的预期结果

BP 1309 GD

但是我得到的结果是

BP 1309 6D

我尝试将轮廓切成 3 片

是的,它正在工作,但是如果我将差异图像插入此方法,则某些图像无法识别,例如这个

字母 N 无法识别,但如果使用第一种方法,它可以工作

这是代码

import numpy as np
import pytesseract
import cv2
import os

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
image_path = "data"

for nama_file in sorted(os.listdir(image_path)):
    print(nama_file)
    # Load image, create blank mask, convert to HSV, define thresholds, color threshold
    I = cv2.imread(os.path.join(image_path, nama_file))
    dim = (500, 120)
    I = cv2.resize(I, dim, interpolation = cv2.INTER_AREA)
    (thresh, image) = cv2.threshold(I, 127, 255, cv2.THRESH_BINARY)
    result = np.zeros(image.shape, dtype=np.uint8)
    result = 255 - result
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    lower = np.array([0,0,0])
    upper = np.array([179,100,130])
    mask = cv2.inRange(hsv, lower, upper)
    slices = []
    slices.append(result.copy())
    slices.append(result.copy())
    slices.append(result.copy())
    i = 0
    j = 0
    xs = []

    # Perform morph close and merge for 3-channel ROI extraction
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)
    extract = cv2.merge([close,close,close])

    # Find contours, filter using contour area, and extract using Numpy slicing
    cnts = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    boundingBoxes = [cv2.boundingRect(c) for c in cnts]
    (cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
    key=lambda b:b[1][0], reverse=False))
    for c in cnts:
        x,y,w,h = cv2.boundingRect(c)
        area = w * h
        ras = format(w / h, '.2f')
        if h >= 40 and h <= 70 and w >= 10 and w <= 65 and float(ras) <= 1.3:
            cv2.rectangle(I, (x, y), (x + w, y + h), (36,255,12), 3)
            result[y:y+h, x:x+w] = extract[y:y+h, x:x+w]
            # Slice
            xs.append(x)
            if i > 0:
                if (xs[i] - xs[i-1]) > 63:
                    j = j+1
            i = i + 1
            slices[j][y:y+h, x:x+w] = extract[y:y+h, x:x+w]

    # Split throw into Pytesseract
    j=0
    for s in slices:
        cv2.imshow('result', s)
        cv2.waitKey()
        if j != 1 :
            data = pytesseract.image_to_string(s, lang='eng',config='--psm 6 _char_whitelist=ABCDEFGHIJKLMNOPQRTUVWXYZ')
        else :
            data = pytesseract.image_to_string(s, lang='eng',config='--psm 6 _char_whitelist=1234567890')
        print(data)

    # Block throw into Pytesseract
    data = pytesseract.image_to_string(result, lang='eng',config='--psm 6')
    print(data)

    cv2.imshow('image', I)
    cv2.imshow('close', close)
    cv2.imshow('extract', extract)
    cv2.imshow('result', result)
    cv2.waitKey()

也许有人知道为什么会发生这种情况以及应该怎么做?

提前致谢

【问题讨论】:

    标签: python opencv tesseract alpr


    【解决方案1】:

    我尝试了很多东西并找到了某种解决方案:

    应用扩张形态操作使字母变细:

    # Split throw into Pytesseract
    j=0
    for s in slices:
        cv2.imshow('result', s)
        cv2.waitKey(1)
        if j != 1:
            data = pytesseract.image_to_string(s, config="-c tessedit"
                                                          "_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
                                                          " --psm 6"
                                                          " ")
    
    
            if data=='':            
                s = cv2.dilate(s, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5)))
                cv2.imshow('cv2.dilate(s)', s)
                cv2.waitKey(1)
                data = pytesseract.image_to_string(s, config="-c tessedit"
                                                             "_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
                                                             " --psm 6"
                                                             " ")
        else:
            pytesseract.pytesseract.tessedit_char_whitelist = '1234567890'
            data = pytesseract.image_to_string(s, lang='eng',config='--psm 6 _char_whitelist=1234567890')
    
        print(data)
    

    这种行为很奇怪。
    有很多抱怨,建议的解决方案不起作用。

    例如看下面的帖子:Tesseract does not recognize single characters

    至少我学会了如何使用_char_whitelist选项(你需要添加-c tessedit)...

    我认为解决方案不够稳健(可能是偶然的)。
    我认为当前版本的 Tesseract 没有简单的解决方案。

    【讨论】:

    • 嗨@Rotem 感谢您的解决方案,我已经尝试过了,它正在工作,接下来让我尝试一堆样本:D
    【解决方案2】:

    我可以通过在 ubuntu shell 中使用一个简单的命令立即解码板。但为了做到这一点,您必须将 tesseract 从版本 4 升级到 5。

    license plate

    tesseract a364k.png stdout -l eng --oem 3 --psm 7 -c tessedit_char_whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "
    BP 1309 GD
    

    在您的代码中,您可以将其添加到配置中

    -l eng --oem 3 --psm 7 -c tessedit_char_whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "
    

    【讨论】:

    • 嗨,@us2018 我尝试了上面的代码,我使用 CMD 的第一个代码正在工作,但第二个仍然是错误我得到了 BP 1309 6D
    • 我像这样添加第二个 data = pytesseract.image_to_string(result,config='-l eng --oem 3 --psm 7 -c tessedit_char_whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "')
    • 我得到了与 CMD 一致的结果。我正在使用 Ubuntu 18.04 和 tesseract 5.0.0-alpha-647-g4a00。你能发布原始图像吗?
    • 是的,我使用 Windows 10 和 tesseract v5.0.0-alpha.20200328 使用 CMD 得到正确的结果,但是当使用 python 时它不起作用,我使用 python Python 3.8.2,这是@ 987654322@
    • 当我使用你的代码和原始图像时,我得到了相同的结果。您发布的图像 (a364k.png) 与结果图像之间存在细微差别。然而,如果图像倾斜,问题似乎是 tesseract 无法正确识别图像。所以我旋转了图像(使用 gimp),然后通过 CMD 进行 OCR 并且它起作用了。我认为您应该尝试稍微旋转一下图像,然后使用 tesseract。
    猜你喜欢
    • 2013-10-16
    • 1970-01-01
    • 2014-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 2019-08-16
    • 1970-01-01
    • 2010-12-30
    相关资源
    最近更新 更多