Что я могу сделать, чтобы улучшить результат распознавания с помощью pytesseract?

Я пытаюсь применить OCR с помощью OpenCV и Python-tesseract для преобразования следующего изображения в текст: Исходное изображение.

Но tesseract пока не удалось правильно прочитать изображение. Вместо этого он гласит: uleswylly Bie7 Srp a7.

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

  1. Сначала я масштабирую изображение:
# Image scaling
def set_image_dpi(img):
    # Get current dimensions of the image
    height, width = img.shape[:2]

    # Define scale factor
    scale_factor = 6

    # Calculate new dimensions
    new_height = int(height * scale_factor)
    new_width = int(width * scale_factor)

    # Resize image
    return cv2.resize(img, (new_width, new_height))

Результат изображения: result1.png

  1. Нормализуйте изображение:
# Normalization
norm_img = np.zeros((img.shape[0], img.shape[1]))
img = cv2.normalize(img, norm_img, 0, 255, cv2.NORM_MINMAX)

Результат изображения: result2.png

  1. Затем я удаляю шум:
# Remove noise
def remove_noise(img):
    return cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 15)

Результат изображения: result3.png

  1. Получите изображение в градациях серого:
# Get grayscale
def get_grayscale(img):
    return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Результат изображения: result4.png

  1. Применить пороговое значение:
# Thresholding
def thresholding(img):
    return cv2.threshold(img, 150, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) [1]

Результат изображения: result5.png

  1. Инвертировать цвет изображения:
# Invert the image
def invert(img):
    return cv2.bitwise_not(img)

Результат изображения: result6.png

  1. Наконец, я передаю изображение в pytesseract:
# Pass preprocessed image to pytesseract
text = pytesseract.image_to_string(img)
print("Text found: " + text)

вывод питессеракта: "uleswylly Bie7 Srp a7"

Я хотел бы улучшить предварительную обработку, чтобы pytesseract действительно мог читать изображение? Любая помощь будет принята с благодарностью!

Заранее спасибо,

Стинерт

Измените размер, как вы это сделали, затем установите порог для белых букв, используя cv2.inRange(). Это должно дать только буквы на черном фоне. Затем инвертируйте это и сделайте pytesseract на этом.

fmw42 17.04.2023 21:29
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
85
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема немного сложная, без переоснащения решения проблемы...

Предположим, что текст яркий, бесцветный и окружен цветными пикселями. Можно также предположить, что фон относительно однороден.

Мы можем начать с result3.png и использовать следующие этапы:

  • Добавьте отступ цветом верхнего левого пикселя.
    Отступ используется в качестве подготовки к floodFill (требуется, потому что некоторые цветные пиксели касаются полей изображения).
  • Залейте фон голубым цветом.
    Обратите внимание, что выбранный цвет немного завышен, потому что уровень насыщенности должен быть близок к уровню красных пикселей.
  • Преобразуйте цветовое пространство BGR в HSV и извлеките канал насыщения.
  • Примените пороговое значение (используйте cv2.THRESH_OTSU для автоматического порогового значения).
  • Примените pytesseract.image_to_string к пороговому изображению.

Пример кода:

import cv2
import numpy as np
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'  # May be required when using Windows

img = cv2.imread('result3.png')  # Read result3.png

# Add padding with the color of the top left pixel
pad_color = img[0, 0, :]
padded_img = np.full((img.shape[0]+10, img.shape[1]+10, 3), pad_color, np.uint8)
padded_img[5:-5, 5:-5, :] = img

cv2.floodFill(padded_img, None, (0, 0), (255, 100, 100), loDiff=(10, 10, 10), upDiff=(10, 10, 10))  # Fill the background with blue color.
cv2.imwrite('result7.png', padded_img)

# Convert from BGR to HSV color space, and extract the saturation channel.
hsv = cv2.cvtColor(padded_img, cv2.COLOR_BGR2HSV)
s = hsv[:, :, 1]
cv2.imwrite('result8.png', s)

# Apply thresholding (use `cv2.THRESH_OTSU` for automatic thresholding)
thresh = cv2.threshold(s, 0, 255, cv2.THRESH_OTSU)[1]
cv2.imwrite('result9.png', thresh)

# Pass preprocessed image to PyTesseract
text = pytesseract.image_to_string(thresh, config = "--psm 6")
print("Text found: " + text)

Выход:
Text found: Jules -Lv: 175 -P.17


result7.png (после флуда):

result8.png (после извлечения канала насыщения):

result9.png (после порога):

Это сработало отлично! Я не подумал о добавлении отступов и настройке насыщенности изображения перед порогом. Спасибо

Steenert 17.04.2023 23:29

Другие вопросы по теме