Распознавание изображения в текст с использованием Tesseract-OCR лучше, когда изображение предварительно обрабатывается вручную с помощью GIMP, чем мой код Python

Я пытаюсь написать код на Python для ручной предварительной обработки и распознавания изображений с помощью Tesseract-OCR.

Ручная обработка:
Чтобы вручную распознать текст для одного изображения, я предварительно обрабатываю изображение с помощью GIMP и создаю изображение в формате TIF. Затем я скармливаю его Tesseract-OCR, который распознает его правильно.

Чтобы предварительно обработать изображение с помощью GIMP, я делаю -

  1. Измените режим на RGB / оттенки серого
    Меню - Изображение - Режим - RGB
  2. Установка пороговых значений
    Меню - Инструменты - Инструменты цвета - Пороговые значения - Авто
  3. Измените режим на "Индексированный"
    Меню - Изображение - Режим - Индексированный
  4. Изменить размер / масштабировать до ширины ›300 пикселей
    Меню - Изображение - Масштабировать изображение - Ширина = 300
  5. Сохранить как Tif

Потом кормлю его тессеракт -

$ tesseract captcha.tif output -psm 6

И все время получаю точный результат.

Код Python:
Я попытался воспроизвести описанную выше процедуру с помощью OpenCV и Tesseract -

def binarize_image_using_opencv(captcha_path, binary_image_path='input-black-n-white.jpg'):
    im_gray = cv2.imread(captcha_path, cv2.CV_LOAD_IMAGE_GRAYSCALE)
    (thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # although thresh is used below, gonna pick something suitable
    im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]
    cv2.imwrite(binary_image_path, im_bw)

    return binary_image_path

def preprocess_image_using_opencv(captcha_path):
    bin_image_path = binarize_image_using_opencv(captcha_path)

    im_bin = Image.open(bin_image_path)
    basewidth = 300  # in pixels
    wpercent = (basewidth/float(im_bin.size[0]))
    hsize = int((float(im_bin.size[1])*float(wpercent)))
    big = im_bin.resize((basewidth, hsize), Image.NEAREST)

    # tesseract-ocr only works with TIF so save the bigger image in that format
    tif_file = "input-NEAREST.tif"
    big.save(tif_file)

    return tif_file

def get_captcha_text_from_captcha_image(captcha_path):

    # Preprocess the image befor OCR
    tif_file = preprocess_image_using_opencv(captcha_path)

    #   Perform OCR using tesseract-ocr library
    # OCR : Optical Character Recognition
    image = Image.open(tif_file)
    ocr_text = image_to_string(image, config="-psm 6")
    alphanumeric_text = ''.join(e for e in ocr_text)

    return alphanumeric_text    

Но я не получаю такой точности. Что я пропустил?

Обновление 1:

  1. Исходное изображение
     введите описание изображения здесь
  2. Изображение Tif, созданное с помощью GIMP
     введите описание изображения здесь
  3. Изображение Tif, созданное моим кодом Python
     введите описание изображения здесь

Обновление 2:

Этот код доступен по адресу https://github.com/hussaintamboli/python-image-to-text


person Hussain    schedule 09.09.2015    source источник
comment
попробуйте сопоставить вывод вашего скрипта python и gimp на различных этапах, таких как comparing the binary outputs и т. д.   -  person ZdaR    schedule 09.09.2015
comment
Я вижу, что Тифы не выглядят одинаково   -  person Hussain    schedule 09.09.2015
comment
Тогда, вероятно, есть проблема с вашей процедурой определения порога, вам нужно проанализировать, как автоматическое определение порога в GIMP на самом деле работает в бэкэнде, можете ли вы прикрепить необходимые изображения вместе с вопросом?   -  person ZdaR    schedule 09.09.2015
comment
Единственная разница между GIMP и вашей реализацией python заключается в добавлении дополнительной границы в изображение python, а на выходе GIMP штрихи текста довольно плавные. Я бы посоветовал вам избавиться от лишней границы.   -  person ZdaR    schedule 09.09.2015
comment
да. Я могу видеть это. Я постараюсь убрать эти штрихи. Я не думаю, что граница вызывает какие-либо проблемы, потому что текст, который распознал код Python, неверен только на один символ. Не могли бы вы дать еще несколько подсказок или фрагментов кода?   -  person Hussain    schedule 09.09.2015
comment
Какой именно персонаж несовместим?   -  person ZdaR    schedule 09.09.2015
comment
Выдает на выходе - 88BC'7F. (Обратите внимание на дополнительную одинарную кавычку в распознанном тексте)   -  person Hussain    schedule 09.09.2015
comment
Вы можете попробовать некоторые методы, такие как erosion и dilation, чтобы заполнить отверстия, а также удалить маленькие точки на обратной стороне соответственно.   -  person ZdaR    schedule 10.09.2015
comment
Обновление: проверьте github.com/hussaintamboli/python-image-to-text   -  person Hussain    schedule 12.02.2018
comment
Вау, похоже, вы пытаетесь написать программу для создания робота, когда используется рекапча.   -  person Eamonn Kenny    schedule 17.04.2018
comment
@Hussain Были ли у вас проблемы с ограничивающими рамками?   -  person Godfather    schedule 30.07.2019


Ответы (2)


Если результат лишь минимально отличается от ожидаемого (например, лишний 'и т. Д., Как предлагается в ваших комментариях), попробуйте ограничить распознавание символов ожидаемым набором символов (например, буквенно-цифровым).

person Aurelian    schedule 26.10.2016

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

Для каждой однозначной цифры

    1. Upsample
    1. Add border

Для точного распознавания требуется повышающая дискретизация. Добавление границы к изображению центрирует цифру.

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here
8 8 B C 7 F

Код:


import cv2
import pytesseract

img = cv2.imread('Iv5BS.jpg')
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.threshold(gry, 128, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

(h_thr, w_thr) = thr.shape[:2]
s_idx = 2
e_idx = int(w_thr/6) - 20
result = ""

for _ in range(0, 6):
    crp = thr[5:int((6*h_thr)/7), s_idx:e_idx]
    (h_crp, w_crp) = crp.shape[:2]
    crp = cv2.resize(crp, (w_crp*2, h_crp*2))
    crp = cv2.copyMakeBorder(crp, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=255)
    s_idx = e_idx
    e_idx = s_idx + int(w_thr/6) - 7
    txt = pytesseract.image_to_string(crp, config="--psm 6")
    result += txt[0]
    cv2.imshow("crp", crp)
    cv2.waitKey(0)

print(result)

Результат:

88BC7F
person Ahx    schedule 11.02.2021