Разпознаването на изображение към текст с помощта на Tesseract-OCR е по-добро, когато изображението е предварително обработено ръчно с помощта на Gimp, отколкото моя код на Python

Опитвам се да напиша код на Python за ръчна предварителна обработка и разпознаване на изображения с помощта на Tesseract-OCR.

Ръчен процес:
За ръчно разпознаване на текст за едно изображение, обработвам предварително изображението с помощта на Gimp и създавам TIF изображение. След това го подавам на Tesseract-OCR, който го разпознава правилно.

За да обработя предварително изображението с помощта на Gimp, правя -

  1. Променете режима на RGB / Grayscale
    Меню -- Изображение -- Режим -- RGB
  2. Праг
    Меню -- Инструменти -- Инструменти за цвят -- Праг -- Автоматично
  3. Променете режима на Индексиран
    Меню -- Изображение -- Режим -- Индексиран
  4. Преоразмеряване / Мащабиране до ширина › 300px
    Меню -- Изображение -- Мащабиране на изображението -- Ширина=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
Виждам, че Tif-ите не изглеждат по същия начин   -  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
Уау, изглежда, че се опитвате да напишете програма за създаване на робот, когато се използва recaptcha.   -  person Eamonn Kenny    schedule 17.04.2018
comment
@Hussain имали ли сте проблеми с ограничаващите полета?   -  person Godfather    schedule 30.07.2019


Отговори (2)


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

person Aurelian    schedule 26.10.2016
comment
Опитвах това преди много време. Можете да проверите моя код github.com/hussaintamboli/python-image-to-text. Ще се радвам да обединя всички подобрения, ако вдигнете PR - person Hussain; 12.02.2018

Вече сте приложили простия праг. Липсващата част е, че трябва да прочетете изображенията едно по едно

За всяка едноцифрена цифра

    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