Статья Распознаем текст на изображении двумя библиотеками с помощью Python

Уже довольно давно признанным лидером по распознаванию текста в пользовательском сегменте является Abbyy FineReader. К тому же, она не только позволяет распознавать тексты, но, также и сканировать документы с помощью сканера. Но, речь не о ней. А о том, что в области распознавания текста может предложить Python. Давайте рассмотрим две популярные библиотеки и попробуем сравнить качество распознавания.

001.png

Если честно, то узнав, как давно разрабатывалась первоначальная версия Tesseract OCR, я был удивлен. Ее разработка велась с середины 80-х по середину 90-х годов компанией Hewlett-Packard. После была благополучно забыта аж на целых 10 лет. В 2006 году была выкуплена Google, а ее исходные тексты стали открыты для разработчиков. И, дело сдвинулось с мертвой точки. В настоящий момент существует версия 5.0, которая уже очень далеко ушла от своей библиотеки-прародительницы.

Разработка EasyOCR была представлена общественности 24 июля 2020 года. Так что, в отличие от Tesseract, эта библиотека очень молодая, но, тем не менее, подающая большие надежды. Для распознавания доступны более 40 языков, а код написан на Python с использованием фреймворка PyTorch.


Что понадобиться?

Установить easyocr. Библиотека довольно большая и в процессе установки подгружает необходимые для работы зависимости. Поэтому будьте готовы к тому, что установка займет продолжительное время. Впрочем, здесь все зависит от скорости вашего интернета и мощности компьютера. Для установки пишем в терминале:

pip install easyocr

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

screenshot1.png


Затем установим Pillow. С его помощью мы будем открывать картинки для загрузки в tesseract.

pip install Pillow

А теперь нужно установить Tesseract OCR. Если у вас операционная система Windows, то в коде нужно будет прописывать на строчку кода больше. Установка библиотеки подробно описана вот здесь. При установке в Windows будьте внимательны и выберите нужные вам языки распознавания в инсталляторе. В Linux и Mac дополнительные языки скачиваются вот с этой страницы, после чего скачанный файл кладется в папку с tesseract.

После установки основной библиотеки нужно установить модуль для Python. Пишем в терминале:

pip install pytesseract

И наконец, когда уже все будет установлено, импортируем необходимые модули в скрипт:

Python:
import os.path

import easyocr
import pytesseract
from PIL import Image

Если вы используете ОС Windows, вам нужно будет дополнительно прописать вот такую конструкцию:

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

где указывается путь к исполняемому файлу.


Функция для сканирования изображения с помощью tesseract

Давайте создадим функцию для распознавания текста на изображении с помощью tesseract. Я назову ее teseract_recognition(path_img), и на входе она принимает всего лишь один параметр, это путь к файлу изображения.

Python:
def teseract_recognition(path_img):
    return pytesseract.image_to_string(Image.open(path_img), lang='rus+eng', config=r'--oem 3 --psm 6')

Здесь, с помощью функции image_to_string распознается изображение. Оно принимает, в данном случае следующие параметры:

- Изображение для распознавания. Здесь мы сразу же открываем изображение с помощью функции Image, куда передается путь к файлу.
- Язык распознавания. В данном случае указан русский + английский. В зависимости от ваших потребностей можете установить какой-то один язык.
- Конфиг. Первый параметр, это OCR Engine Mode, режим работы «движка» для распознавания. Оставим его без изменений. А вот с psm можно поэкспериментировать. psm – это page segmentation mode, то есть режим сегментации страниц. Чуть более подробно про значения данного режима можно глянуть тут.

И возвращаем распознанный текст туда, откуда он был вызван. По сути, в простейшем варианте, весь код уместился в двух строчках кода. А если убрать объявление функции, то уместиться и в одной.


Функция распознавания текста с помощью easyocr

Теперь давайте сделаем функцию, которая также будет распознавать текст, но уже с помощью другой библиотеки. Создадим функцию easyocr_recognition(path_img). Здесь на вход принимается только путь к файлу с изображением.

Python:
def easyocr_recognition(path_img):
    return easyocr.Reader(["ru"]).readtext(path_img, detail=0, paragraph=True, text_threshold=0.8)

Создадим объект easyocr.Reader, в который передадим список с языками для распознавания. В нашем случае это русский. Можно указать английский и многие другие. Соответственно, если вам еще нужен один язык, укажите его обозначение через запятую. Затем вызываем функцию readtext, в которую передаем следующие параметры:

- Путь к файлу с изображением;
- Детализация. По умолчанию данный параметр равен 1 и выводит на экран, помимо текста, еще и параметры отступов и прочую служебную информацию, а также порог достоверности текста, который по умолчанию равен 0.7;
- Автоматическое разбиение текста на параграфы. В противном случае текст выводиться по словам;
- Порог достоверности текста.

Как видите, здесь также в простом варианте все уложилось в две строчки.

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


Функция сохранения текста в файл

Создадим функцию сохранения распознанного текста в файл. Я назвал ее save_text(text, name). На входе она принимает текст для сохранения и название для файла с текстом.

Python:
def save_text(text, name):
    with open(f'{name}.txt', 'w', encoding='utf-8') as file:
        file.write(text)
    print(f'[+] Распознанный текст сохранен в файл: "{name}.txt"')
    main()
    return

Ну, а дальше сохраняется текст и выводиться сообщение об успешном завершении.

Ну и функция main().

Python:
def main():
    path_img = input('\n[+] Введите путь к картинке\n - Для выхода введите x\n   >>> ')
    if path_img == "x":
        exit(0)
    if not os.path.exists(path_img):
        print('[+] Картинки не существует')

    user_change = input('\n[+] Выберите библиотеку для распознавания текста:\n   [1] Tesseract OCR\n   '
                        '[2] EasyOCR\n   [3] Выход\n   >>> ')
    if user_change == "1":
        save_text(teseract_recognition(path_img), os.path.split(path_img)[1].split(".")[0])
    elif user_change == '2':
        save_text(easyocr_recognition(path_img), os.path.split(path_img)[1].split(".")[0])
    elif user_change == "3":
        exit(0)
    else:
        print('[+] Неопознанный ввод. Повторите все сначала')
        main()

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

Python:
# pip install easyocr
# pip install pytesseract
# pip install Pillow

import os.path

import easyocr
import pytesseract
from PIL import Image

# путь к исполняемому файлу tesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"


# распозавание с помощью pytesseract, открытие картинки PIL.Image
def teseract_recognition(path_img):
    return pytesseract.image_to_string(Image.open(path_img), lang='rus+eng', config=r'--oem 3 --psm 6')


# распознавание с помощью easyocr, параметры: отключена детализация вывода,
# включены параграфы и установлена точность текста
def easyocr_recognition(path_img):
    return easyocr.Reader(["ru"]).readtext(path_img, detail=0, paragraph=True, text_threshold=0.8)


# сохранение текста в текстовый файл
def save_text(text, name):
    with open(f'{name}.txt', 'w', encoding='utf-8') as file:
        file.write(text)
    print(f'[+] Распознанный текст сохранен в файл: "{name}.txt"')
    main()
    return


# ввод данных и выбор библиотеки для распознавания
def main():
    path_img = input('\n[+] Введите путь к картинке\n - Для выхода введите x\n   >>> ')
    if path_img == "x":
        exit(0)
    if not os.path.exists(path_img):
        print('[+] Картинки не существует')

    user_change = input('\n[+] Выберите библиотеку для распознавания текста:\n   [1] Tesseract OCR\n   '
                        '[2] EasyOCR\n   [3] Выход\n   >>> ')
    if user_change == "1":
        save_text(teseract_recognition(path_img), os.path.split(path_img)[1].split(".")[0])
    elif user_change == '2':
        save_text(easyocr_recognition(path_img), os.path.split(path_img)[1].split(".")[0])
    elif user_change == "3":
        exit(0)
    else:
        print('[+] Неопознанный ввод. Повторите все сначала')
        main()


if __name__ == "__main__":
    main()


Впечатления и выводы

Были опробованы обе библиотеки на разных русских текстах. В сводном виде они ниже на скриншоте:

000.jpg

Ну и дальше результаты:

Изображение 01:

Tesseract:
Tesseract 01.png

EasyOCR:
EasyOCR 01.png

Изображение 02:

Tesseract:
Tesseract 02.png

EasyOCR:
EasyOCR 02.png

Изображение 03:

Tesseract:
Tesseract 03.png

EasyOCR:
EasyOCR 03.png

Изображение 04:

Tesseract:
Tesseract 04.png

EasyOCR:
EasyOCR 04.png

Здесь могу сказать, что может быть у меня не оптимальные настройки. Допускаю, но в данном случае tesseract справился лучше. Причем, скорость его работы намного выше, чем easyocr. Быть может, тут сыграл значение один немаловажный фактор, что данная библиотека использует технологию CUDA, а на моем компьютере графика ее не поддерживает. И если бы она была, все работало бы быстрее. Но, что имеем, то имеем. И easyocr распознавал текст долго и зачастую не совсем верно.

Думаю, что его можно использовать, если оптимизировать скорость работы, для распознавания нужного текста. К примеру, для поиска определенного номера машины на фото. Это как заявлено у них в документации. Кстати, попробовал номер. И да, распознался более качественно, чем tesseract.

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
 
Последнее редактирование:

TheLast

Green Team
17.11.2021
10
4
Спасибо большое автору за статью! Познавательно.
 

batu5ai

Grey Team
31.01.2018
101
103
OCR и вообще тема компьютерного зрения для осинта -> топич; для тестирования - тоже(я про обход капчи).
 
  • Нравится
Реакции: Johan Van
02.03.2021
380
250
Хватит писать прекрасные статьи, благодаря им мне пришлось вернуться к брошенному и забытому ЯП Python. И учить его снова. Если так и дальше пойдет я начну их реализовывать в жизни. А что же будет дальше, сам начну писать подобные статьи.
Остановись ты с подвигаешь народ к развитию и решаешь кучу разных вопросов.
 
  • Нравится
Реакции: And4R
Мы в соцсетях: