Предобработка изображений для OCR

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

Введение

Люди, занимающиеся документооборотом, думаю часто сталкиваются с задачей сортировки отсканированных документов по папкам, к примеру протоколы в одну папку, удостоверения в другую да и переименовать файл тоже бы не помешало. Вот для этого можно использовать OCR.

OCR (англ. optical character recognition) - программа натренированная для распознавания текста с изображения.

Я покажу пример работы с OCR Tesseract (свободная программа распознавания текста от Google), так как это самый популярный вариант.

Стек

Для обработки нам понадобятся:

➤ pytesseract (pip install pytesseract)

➤ opencv-python (pip install opencv-python)

➤ numpy (pip install numpy)

➤ pillow (pip install pillow)

Предобработка изображений для OCR

Pytesseract - Это модуль обертка для модели, самая модель tesseract написана на C++.

Opencv - библиотека для машинного зрения и обработки изображений, так же написанная на C++.

Numpy - python-библиотека для быстрых математических операций над данными, а быстрая она из-за языков C, C++ и Fortran, на которых она написана.

Pillow - библиотека для работы с изображениями и их обработки, но в нашем случае мы воспользуемся ею лишь один в одной функции и её можно спокойно заменить на opencv.

Определение класса и его полей

Инициируем класс ImageReader и задаем обязательный аргумент в виде пути к изображению и сохраняем его как атрибут класса.

Ну и конечно же создаём переменную с путём до файла tesseract.exe, а также шаблон config для работы OCR.

Предобработка изображений для OCR

Функция correct_image_orientation

И так, снимки могут быть с различной ориентацией, думаю это понятно, но tesseract такой текст вряд ли прочитает и поэтому мы должны это исправить.

Воспользуемся классом Image библиотеки Pillow и откроем изображение передав путь в экземпляр класса.

Далее используем библиотеку pytesseract для получения информации о изображении. Вызовем функцию image_to_osd и передадим ей наше изображение, а так же зададим формат вывода dict.

Из полученного словаря получаем значение по ключу orientation и в зависимости от него поворачиваем изображение используя метод transpose для экземпляра Image.

Вот и всё, теперь просто возвращаем это экземпляр.

Предобработка изображений для OCR

Функция preprocess_image

Что бы tesseract работал хорошо, символы должны быть достаточно разборчивыми и желательно, что бы минимальная толщина контура символов была больше 2-3 пикселей. Для этого мы увеличиваем изображение в 3 раза (вы по желанию можете увеличить больше или меньше).

Первым делом мы должны получить высоту и ширину изображения умножить их на 3 и передать их функции resize вместе с методом интерполяции.

Если вы хотите именно увеличить изображение, то рекомендую использовать cv2.INTER_CUBIC или cv2.INTER_LINEAR.

Для дальнейшего перевода в бинарный вид (это когда на изображении только два цвета белый и чёрный) методом OTSU, мы меняем цвета изображения из RGB в оттенки серого, не забыв добавить небольшое размытие для удаления части шумов.

Можно использовать и бинарный метод вместо OTSU, но тогда вам стоит поискать нужное пороговое значение, по моему опыту это в районе 60 плюс минус 10 единиц.

Предобработка изображений для OCR

Функция remove_noise

Размытие не позволяет нам избавится от всех шумов полностью. Что бы сделать это нам необходимо провернуть отдельные махинации.

Первым делом получаем негатив из изображения, это необходимо для лучшего определения шума.

Создадим шаблон через функцию getStructuringElement и помещаем в переменную kernel

Передаём kernel в функции erode и dilate с количеством итераций равному 1.

cv2.erode - функция математической эрозии изображений, позволяющей получать размытое изображение.cv2.dilate - функция математического расширения изображений, которое противоположно эрозии.

В результате получается изображения, в которой различные мелкие точки, путающие tesseract, исчезают.

Предобработка изображений для OCR

Функция read_image

Осталось сделать последнее, прочитать обработанное изображение используя функцию image_to_string из библиотеки pytesseract, передав в неё изображение и config.

Так как config у нас шаблонный, мы должны заполнить его, в качестве языков буде rus+eng, oem (OCR Engine Mode) будет равен 2, т.е. legacy+LSTM (long short term memory network), psm (Page Segmentation Mode) - 3 (Fully automatic page segmentation, but no OSD)

Предобработка изображений для OCR

Функция main

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

Предобработка изображений для OCR

Заключение

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

Для интереса можно сохранить обработанное изображение и увидеть как оно изменилось.

Исходное изображение
Исходное изображение
Полученное в результате обработки
Полученное в результате обработки
3
1 комментарий