Как извлечь текст из изображения после применения контура в python? - PullRequest
3 голосов
/ 06 января 2020

Итак, я применил контур на большом изображении и достиг следующей обрезанной части изображения:

enter image description here

enter image description here

Но теперь, без использования модели машинного обучения, как мне на самом деле получить изображение в текстовую переменную? Я узнал о сопоставлении с шаблоном, но я не понимаю, как мне действовать дальше. У меня есть изображения букв и цифр (названные в соответствии с их значением изображения), хранящиеся в каталоге, но как мне сопоставить каждое из них и получить текст в виде строки? Я не хочу использовать какую-либо модель или библиотеку ML, например pyTesseract.

Буду признателен за любую помощь.

Редактировать:

Код, который я пробовал для сопоставления с шаблоном.

def templateMatch(image):
    path = "location"

    for image_path in os.listdir(path + "/characters-images"):
        template = cv2.imread(os.path.join(path, "characters-images", image_path))
        template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)

        template = template.astype(np.uint8)
        image = image.astype(np.uint8)

        res = cv2.matchTemplate(template, image, cv2.TM_SQDIFF_NORMED)
        mn, _, mnLoc, _ = cv2.minMaxLoc(res)

        if res is not None:
            return image_path.replace(".bmp", "")


def match(image):
    plate = ""
    # mask = np.zeros(image.shape, dtype=np.uint8)
    # print(image.shape)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # print(image.shape)
    # print(image)
    thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

    cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    (cnts, _) = contours.sort_contours(cnts, method="left-to-right")

    for con in cnts:
        area = cv2.contourArea(con)

        if 800 > area > 200:
            x, y, w, h = cv2.boundingRect(con)
            # cv2.drawContours(mask, [c], 1, (255, 0, 0), 2)
            temp = thresh[y:y+h, x:x+w]

            character = templateMatching(temp)

            if character is not None:
                plate += character

    return plate

Ответы [ 2 ]

3 голосов
/ 06 января 2020

Как мне на самом деле получить изображение в текстовую переменную? Я узнал о сопоставлении с шаблоном, но не понимаю, как мне действовать дальше.

Сопоставление с шаблоном используется для определения местоположения объекта на изображении по заданному шаблону, не для извлечения текста из изображения. Сопоставление шаблона с положением объекта на изображении не поможет получить текст в виде строки. Для примеров того, как применить динамическое сопоставление с шаблоном варианта c, посмотрите как изолировать все внутри контура, масштабировать его и проверить сходство с изображением? и Python Обнаружение линии OpenCV для обнаружения символа X на изображении . Я не понимаю, почему не хотел бы использовать библиотеку OCR. Если вы хотите извлечь текст из изображения как строковую переменную, вы должны использовать какой-то тип глубокого / машинного обучения. PyTesseract, вероятно, самый простой. Вот решение с использованием PyTesseract


Идея состоит в том, чтобы получить двоичное изображение с использованием порога Оцу, а затем выполнить фильтрацию площади контура и соотношения сторон для извлечения букв / цифр. Отсюда мы используем Numpy нарезку, чтобы обрезать каждый ROI на пустую маску, а затем применить OCR, используя Pytesseract. Вот визуализация каждого шага:

Двоичное изображение

image

Обнаруженные области интереса выделены зеленым цветом

image

Изолированные области интереса на пустой маске, готовой к распознаванию символов

image

Мы используем опцию конфигурации --psm 6, чтобы сообщить Pytesseract о принятии единообразного блока текста. Посмотрите здесь для получения дополнительных параметров конфигурации . Результат от Pytesseract:

XS NB 23

Код

import cv2
import numpy as np
import pytesseract

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

# Load image, create mask, grayscale, Otsu's threshold
image = cv2.imread('1.png')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Filter for ROI using contour area and aspect ratio
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    x,y,w,h = cv2.boundingRect(approx)
    aspect_ratio = w / float(h)
    if area > 2000 and aspect_ratio > .5:
        mask[y:y+h, x:x+w] = image[y:y+h, x:x+w]

# Perfrom OCR with Pytesseract
data = pytesseract.image_to_string(mask, lang='eng', config='--psm 6')
print(data)

cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.waitKey()
0 голосов
/ 06 января 2020

Один из вариантов - рассмотреть ограничивающую рамку вокруг символов и вычислить показатель корреляции между персонажем под рукой и персонажем в тренировочном наборе. Вы сохраните наибольшую оценку корреляции. (Один из SAD, SSD, нормализованная корреляция в градациях серого или просто расстояние Хемминга, если вы работаете с двоичным изображением).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...