Как извлечь отдельные буквы из изображения с помощью PyTesseract? - PullRequest
0 голосов
/ 20 апреля 2020

Я учу себя python и пытаюсь создать простую программу для распознавания букв по изображению. Буквы не в форме предложения или абзаца. Я пытаюсь сделать это, используя cv2 + pytesseract для обнаружения, но я просто не могу заставить его работать надежно. Я начинаю подозревать, что использую не тот инструмент для этой работы, но больше ничего не могу мне помочь.

Это мое контрольное изображение с буквами, которые я хочу извлечь:

enter image description here

В идеале я хотел бы получить букву, а также координаты каждой буквы (ограничивающий прямоугольник). Я смог применить маску и порог к изображению, чтобы получить:

enter image description here

Но я застрял в том, что Pytesseract не может достоверно дайте мне письма индивидуально или даже правильно. Вот мой вывод на консоль ...

$ py main.py --image test.png
D
C UL
UO

Код, который я использую, просто берет черно-белое текстовое изображение и запускает его через pytesseract. Я попытался поиграть с флагом --psm, но, поскольку текст имеет странную форму, мне не повезло.

text = pytesseract.image_to_string(Image.open(filename), config='-l eng --psm 11')
os.remove(filename)
print(text)

1 Ответ

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

Вы можете сегментировать и обрабатывать каждую букву одну за другой. Вы можете посмотреть детали в моем коде.

import cv2
import numpy as np
import pytesseract

img = cv2.imread("xO6JI.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

items = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = items[0] if len(items) == 2 else items[1]

img_contour = img.copy()
for i in range(len(contours)):
    area = cv2.contourArea(contours[i])
    if 100 < area < 10000:
        cv2.drawContours(img_contour, contours, i, (0, 0, 255), 2)

detected = ""
for c in contours:
    x, y, w, h = cv2.boundingRect(c)
    ratio = h/w
    area = cv2.contourArea(c)
    base = np.ones(thresh.shape, dtype=np.uint8)
    if ratio > 0.9 and 100 < area < 10000:
        base[y:y+h, x:x+w] = thresh[y:y+h, x:x+w]
        segment = cv2.bitwise_not(base)

        custom_config = r'-l eng --oem 3 --psm 10 -c tessedit_char_whitelist="ABCDEFGHIJKLMNOPQRSTUVWXYZ" '
        c = pytesseract.image_to_string(segment, config=custom_config)
        print(c)
        detected = detected + c
        cv2.imshow("segment", segment)
        cv2.waitKey(0)

print("detected: " + detected)

cv2.imshow("img_contour", img_contour)

cv2.waitKey(0)
cv2.destroyAllWindows()

Результат

U
O
L
C
D
detected: UOLCD
...