Подтвердить что ты не робот

Предварительная обработка изображения для OCR Tesseract с помощью OpenCV

Я пытаюсь разработать приложение, которое использует Tesseract для распознавания текста из документов, снятых камерой телефона. Я использую OpenCV для предварительной обработки изображения для лучшего распознавания, применяя размытие по Гауссу и метод Threshold для бинаризации, но результат довольно плохой.

Вот изображение, которое я использую для тестов: enter image description here

А вот и предварительно обработанное изображение: enter image description here

Какие другие фильтры я могу использовать, чтобы сделать изображение более читабельным для Tesseract?

4b9b3361

Ответ 1

Я описал несколько советов по подготовке изображений для Tesseract здесь: Использование tesseract для распознавания номерных знаков

В вашем примере происходит несколько вещей...

Вы должны сделать текст черным, а остальное изображение белым (а не наоборот). Вот на что настроено распознавание символов. Оттенки серого в порядке, если фон в основном полностью белый, а текст в основном черный; края текста могут быть серыми (сглаженными), и это может помочь распознаванию (но не обязательно - вам придется экспериментировать)

Одна из проблем, с которой вы сталкиваетесь, заключается в том, что в некоторых частях изображения текст действительно "тонкий" (и после выделения порога появляются пропуски в письмах), в то время как в других частях он действительно "толстый" (и начинаются буквы слияние). Тессеракту это не понравится :) Это происходит потому, что входное изображение не равномерно освещено, поэтому один порог не работает везде. Решение состоит в том, чтобы выполнить "локально-адаптивный порог", при котором для каждого соседства изображения рассчитывается различное пороговое значение. Есть много способов сделать это, но посмотрите, например:

Другая проблема, с которой вы столкнулись, заключается в том, что линии не прямые. По моему опыту, Tesseract может работать с очень ограниченной степенью непрямых линий (несколько процентов искажения перспективы, наклона или перекоса), но на самом деле он не работает с волнистыми линиями. Если вы можете, убедитесь, что исходные изображения имеют прямые линии :) К сожалению, нет простого готового ответа на это; вам придется самостоятельно изучить исследовательскую литературу и реализовать один из самых современных алгоритмов (и, если возможно, с открытым исходным кодом - для этого существует реальная потребность в решении с открытым исходным кодом). Поиск в Google Scholar для " извлечения изогнутой линии OCR " поможет вам начать, например:

И наконец: я думаю, что вам лучше работать с экосистемой питона (ndimage, skimage), чем с OpenCV из C++. Оболочки Python для OpenCV подходят для простых вещей, но для того, что вы пытаетесь сделать, они не справятся с работой, вам нужно будет собрать много кусков, которых нет в OpenCV (конечно, вы можете смешивать и сочетать). Реализация чего-то вроде обнаружения изогнутых линий в C++ займет на порядок больше, чем в python (* это верно, даже если вы не знаете python).

Удачи!

Ответ 2

  1. Сканирование со скоростью 300 точек на дюйм (точек на дюйм) официально не является стандартом для оптического распознавания символов (OCR), но считается золотым стандартом.

  2. Преобразование изображения в оттенки серого повышает точность чтения текста в целом.

Я написал модуль, который читает текст в Image, который в свою очередь обрабатывает изображение для получения оптимального результата из OCR, Image Text Reader.

import tempfile

import cv2
import numpy as np
from PIL import Image

IMAGE_SIZE = 1800
BINARY_THREHOLD = 180

def process_image_for_ocr(file_path):
    # TODO : Implement using opencv
    temp_filename = set_image_dpi(file_path)
    im_new = remove_noise_and_smooth(temp_filename)
    return im_new

def set_image_dpi(file_path):
    im = Image.open(file_path)
    length_x, width_y = im.size
    factor = max(1, int(IMAGE_SIZE / length_x))
    size = factor * length_x, factor * width_y
    # size = (1800, 1800)
    im_resized = im.resize(size, Image.ANTIALIAS)
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.jpg')
    temp_filename = temp_file.name
    im_resized.save(temp_filename, dpi=(300, 300))
    return temp_filename

def image_smoothening(img):
    ret1, th1 = cv2.threshold(img, BINARY_THREHOLD, 255, cv2.THRESH_BINARY)
    ret2, th2 = cv2.threshold(th1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    blur = cv2.GaussianBlur(th2, (1, 1), 0)
    ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return th3

def remove_noise_and_smooth(file_name):
    img = cv2.imread(file_name, 0)
    filtered = cv2.adaptiveThreshold(img.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 41,
                                     3)
    kernel = np.ones((1, 1), np.uint8)
    opening = cv2.morphologyEx(filtered, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
    img = image_smoothening(img)
    or_image = cv2.bitwise_or(img, closing)
    return or_image

Ответ 3

Примечание: это должен быть комментарий к Алексу, на который я отвечаю, но он слишком длинный, поэтому я поставил его как ответ.

из "Обзор механизма распознавания текста Tesseract, Рэй Смит, Google Inc." на https://github.com/tesseract-ocr/docs/blob/master/tesseracticdar2007.pdf

"Обработка идет по традиционному пошаговому конвейеру, но некоторые из этапов были необычны в свое время и, возможно, остаются таковыми даже сейчас. Первым этапом является анализ связанных компонентов, в котором хранятся схемы компонентов. Это был В то время это решение требовало вычислительных решений, но имело существенное преимущество: благодаря проверке вложенности контуров и количества контуров дочерних элементов и внуков несложно обнаружить обратный текст и распознать его так же легко, как черно-белый текст Тессеракт был, вероятно, первым механизмом распознавания текста, способным так легко обрабатывать текст в белом цвете ".

Таким образом, кажется, что не нужно иметь черный текст на белом фоне, и должно работать наоборот.

Ответ 4

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

https://www.pyimagesearch.com/2014/08/25/4-point-opencv-getperspective-transform-example/

Пожалуйста, примите ответ, если он вам помог.

Приветствия.