не может правильно распознать номерной знак (Python, OpenCv, Tesseract) - PullRequest
1 голос
/ 11 апреля 2020

Я пытаюсь распознать номерной знак, но получил ошибку, например, неправильно / не читается символ

Вот визуализация каждого шага:

Полученная маска от цветового порога + закрытие морфа

color thresholding morph closing

Фильтр для контуров номерного знака выделен зеленым цветом

countour

Вставленные контуры пластины на чистую маску

contours

Ожидаемый результат от Tesseract OCR

BP 1309 GD

Но результат, который я получил:

BP 1309 6D

, и я пытаюсь нарезать контур на 3 среза

enter image description here

enter image description here enter image description here

и да, это работает, но если я вставлю разностное изображение в этот метод некоторые изображения не распознают, например, это

enter image description here

буква N не распознается, но при использовании первого метода она работает

enter image description here* 10 65 *

Вот код

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()

Может быть, кто-то знает, почему это происходит и что делать?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Я перепробовал много вещей и нашел какое-то решение:

Примените морфологическую операцию расширения, чтобы сделать письмо более тонким:

# 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)

Это поведение очень странное.
Там Есть много жалоб, и предлагаемые решения не работают.

См., Например, следующий пост: Тессеракт не распознает отдельные символы

По крайней мере, я научился использовать опцию _char_whitelist (нужно добавить -c tessedit ) ...

Полагаю, решение недостаточно надежное (возможно, работает случайно).
Я думаю, что в текущей версии Tesseract нет простого решения.

0 голосов
/ 12 апреля 2020

Я могу мгновенно декодировать планшет, используя простую команду в оболочке Ubuntu. Но для этого вы должны обновить tesseract с версии 4 до 5.

номерной знак

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

В своем коде вы можете добавить это в config

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