Как распознать изображение с помощью Tesseract - PullRequest
4 голосов
/ 25 сентября 2019

Я начинаю изучать OpenCV и Tesseract, и у меня возникают проблемы с тем, что кажется очень простым примером.

Вот изображение, которое я пытаюсь распознать, и которое читается как "171 m":

original image

Я делаю некоторую предварительную обработку.Поскольку синий цвет является основным цветом текста, я извлекаю синий канал и применяю простую настройку порога.

img = cv2.imread('171_m.png')[y, x, 0]
_, thresh = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY_INV)

Полученное изображение выглядит следующим образом:

blue channel, simple threshold

Затем добавьте это в Тессеракт с psm 7 для одной строки:

text = pytesseract.image_to_string(thresh, config='--psm 7')
print(text)
>>> lim

Я также попытался ограничить возможные символы, и это становится немного лучше, но не совсем.

text = pytesseract.image_to_string(thresh, config='--psm 7 -c tessedit_char_whitelist=1234567890m')
print(text)
>>> 17m
OpenCV v4.1.1.
Tesseract v5.0.0-alpha.20190708

Любая помощь приветствуется.

Ответы [ 3 ]

0 голосов
/ 25 сентября 2019

Отказ от ответственности: это не решение, а всего лишь попытка частично решить эту проблему.

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

img0 = cv2.imread('171_m.png', 0)
adap_thresh = cv2.adaptiveThreshold(img0, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
text_adth = pytesseract.image_to_string(adap_thresh, config='--psm 7')

После адаптивного порога полученное изображение выглядит следующим образом:

adaptive_thresholded_image

Pytesseract выдает результатas:

171 mi.

Теперь, если вы заранее знаете количество имеющихся символов, вы можете нарезать строку, прочитанную pytesseract, и получить желаемый результат как '171m'.

0 голосов
/ 25 сентября 2019

Перед броском изображения в Pytesseract может помочь предварительная обработка.Желаемый текст должен быть черным, а фон - белым.Вот подход

  • Преобразование изображения в оттенки серого и увеличение изображения
  • Размытие по Гауссу
  • Порог Оцу
  • Инвертированное изображение

После преобразования в оттенки серого мы увеличиваем изображение, используя imutils.resize() и размытие по Гауссу.Отсюда мы получаем порог Оцу для получения двоичного изображения

enter image description here

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

enter image description here

Вывод из Pytesseract с использованием --psm 6

171м

import cv2
import pytesseract
import imutils

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

image = cv2.imread('1.png',0)
image = imutils.resize(image, width=400)
blur = cv2.GaussianBlur(image, (7,7), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
result = 255 - thresh 

data = pytesseract.image_to_string(result, lang='eng',config='--psm 6')
print(data)

cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey()
0 голосов
/ 25 сентября 2019

Мне показалось, что ваше изображение недостаточно резкое, поэтому я применил процесс, описанный в Как увеличить контраст изображения в Python OpenCV , чтобы сначала сделать изображение более резким, а затем продолжить, извлекая синий слойи запустить тессеракт.

Надеюсь, это поможет.

import cv2
import pytesseract 

img = cv2.imread('test.png') #test.png is your original image
s = 128
img = cv2.resize(img, (s,int(s/2)), 0, 0, cv2.INTER_AREA)

def apply_brightness_contrast(input_img, brightness = 0, contrast = 0):

    if brightness != 0:
        if brightness > 0:
            shadow = brightness
            highlight = 255
        else:
            shadow = 0
            highlight = 255 + brightness
        alpha_b = (highlight - shadow)/255
        gamma_b = shadow

        buf = cv2.addWeighted(input_img, alpha_b, input_img, 0, gamma_b)
    else:
        buf = input_img.copy()

    if contrast != 0:
        f = 131*(contrast + 127)/(127*(131-contrast))
        alpha_c = f
        gamma_c = 127*(1-f)

        buf = cv2.addWeighted(buf, alpha_c, buf, 0, gamma_c)

    return buf

out = apply_brightness_contrast(img,0,64)

b, g, r = cv2.split(out) #spliting and using just the blue

pytesseract.image_to_string(255-b, config='--psm 7 -c tessedit_char_whitelist=1234567890m') # the 255-b here because the image has black backgorund and white numbers, 255-b switches the colors
...