пятница, 26 апреля 2013 г.

Обучаем Tesseract

Tesseract - свободная платформа для оптического распознавания текста, исходники которой Google подарил сообществу в 2006 году. Если вы пишите софт для распознавания текста, то вам наверняка приходилось обращаться к услугам этой мощной библиотеки. И если она не справилась с вашим текстом, то выход у вас остаётся один - научить её. Процесс этот достаточно сложный и изобилует не очевидными а порой и прям-таки магическими действиями. Оригинальное описание есть тут. Мне понадобился почти целый день на постижение всей его глубины, поэтому тут я хочу сохранить, надеюсь, более понятный его вариант. Так чтобы помочь себе и другим пройти этот путь в следующий раз быстрее.



0. Что нам нужно

  • Tesseract собственно. 
Сборки этой библиотеки есть под windows (можно скачать установщик с официального репозитория) и под linux. Для большинства linux-дистрибутивов установить tesseract можно просто через sudo apt-get install tesseract-ocr, мне для моего модного Еlementary OS пришлось добавить источник:
gedit /etc/apt/sources.list
deb http://notesalexp.net/debian/precise/ precise main
wget -O - http://notesalexp.net/debian/alexp_key.asc
apt-key add alexp_key.asc
apt-get update
apt-get install tesseract-ocr

  • Изображение с текстом для тренировки
Желательно чтобы это был реальный текст, который потом придётся распознавать. Важно, чтобы каждый символ шрифта встречался в сканированном фрагменте не менее 5 раз, а желательно - 20 раз. Формат tiff, без сжатия, желательно не многостраничный. Между всеми символами должны быть чётко различимые промежутки. Кладём наше изображение в отдельную директорию и называем в виде <код языка>.<имя шрифта>.exp<номер>.tif.  Изображение может быть не одно и отличаться они должны только номером в наименовании файла. Формат наименований файлов очень важен. На файлы с неверными наименованиями утилиты, которые мы будем использовать будут ругаться ошибками сегментирования и т.п. Для определённости будем считать, что изучаем мы язык ссс и шрифт eee. Таким образом называем файл со сканом тренировочного образца ccc.eee.exp0.tif

1. Создаём и редактируем box-файл
Для того. чтобы отметить символы на изображении и задать их соответствие utf-8 символам текста служат box-файлы. Это обычные текстовые файлы, в которых каждому символу соответствует строка с символом и координатами прямоугольника в пикселях. Первоначально файл генерируем утилитой из пакета tesseract:
tesseract ccc.eee.exp0.tif ccc.eee.exp0 batch.nochop makebox
получили файл ccc.eee.exp0.box в текущей директории. Заглянем в него. Символы в начале строки полностью соответствуют символам в файле? Если это так, то тренировать ничего не нужно, вы можете спать спокойно. В нашем случае скорее всего символы не будут совпадать ни по существу ни по количеству. Т.е. tesseract со словарём по умолчанию не распознал не только символы но и посчитал некоторые из них за два или больше. Возможно часть символов у нас "слипнется", т.е. попадёт в общую коробку и будет распознано как один. Это всё нужно поправить прежде чем идти дальше. Работа нудная и кропотливая, но к счастью для этого есть ряд сторонних утилит. Например я пользовался pyTesseractTrainer-1.03. Открываем им изображение, box-файл с таким же именем он сам подтянет.
Прошло полдня... Вы с чувством глубокого удовлетворения закрываете pyTesseractTrainer (вы ведь не забыли сохранить результат, верно?) и у вас есть корректный box-файл. Теперь можно переходить к следующему этапу.

2. Тренируем Tesseract
tesseract ccc.eee.exp0.tif ccc.eee.exp0 nobatch box.train
Получаем много ошибок, но ищем в конце что-то вроде "Found 105 good blobs". Если цифра существенно больше числа "изучаемых" символов, то есть шанс, что тренировка в целом удалась. Иначе - возвращаемся в начало. В результате этого шага у вас появился файл ccc.eee.exp0.tr

3. Извлекаем набор символов
unicharset_extractor ccc.eee.exp0.box
Получаем набор символов в виде файла unicharset в текущей директории, где каждый символ и его характеристики располагаются в отдельной строке. Тут нашей задачей будет проверить и поправить характеристики символов (вторая колонка в файле). Для маленьких букв алфавита ставим признак 3, для больших 5, для знаков препинания 10 для цифр 8, всё остальное (типа +=-) помечаем 0. Китайские и японские иероглифы помечаем 1. Обычно все признаки стоят правильно, так что этот этап много времени у вас не займёт.

4. Описываем стиль шрифта
Создаём файл ccc.font_properties с единственной строкой: eee 0 0 0 0 0. Тут вначале пишем имя шрифта, затем числом 1 или 0 помечаем наличие у символов стиля (соответственно italic bold fixed serif fraktur). В нашем случае стилей нет, так что оставляем всё по нулям.

5. Кластеры фигур, прототипы и прочая магия
Для дальнейшей учёбы нам понадобиться выполнить ещё три операции. Можете попробовать понять их смысл из официального описания, мне было не до того :). Просто выполняем:
shapeclustering -F ccc.font_properties -U unicharset ccc.eee.exp0.tr
...появится файл shapetable
а затем: 
mftraining -F ccc.font_properties -U unicharset -O ccc.unicharset ccc.eee.exp0.tr
...получим файлы ccc.unicharset, inttemp, pffmtable
и наконец:
cntraining ccc.eee.exp0.tr
...получим файл normproto.

6. Словари
Теоретически заполнение словарей часто используемых слов (и слов вообще) помогает Tesseract-у разбираться в ваших каракулях. Словари использовать необязательно, но если вдруг захочется, делаем файлы frequent_words_list и words_list в которые вписываем (каждое с новой строки) соответственно часто используемые и просто слова языка.
Чтобы сконвертировать эти списки в правильный формат выполняем:
wordlist2dawg frequent_words_list ccc.freq-dawg ccc.unicharset
wordlist2dawg words_list ccc.word-dawg ccc.unicharset

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

8. Последняя команда 
Все файлы нужно переименовать так чтобы их имена начинались с имени языка. Т.е. у нас в директории останутся только файлы:

ccc.box
ccc.inttemp
ccc.pffmtable
ccc.tif
ccc.font_properties
ccc.normproto
ccc.shapetable
ccc.tr
ccc.unicharset

И, наконец, выполняем:
combine_tessdata ccc.
(!) Точка обязательна. В результате получаем файл ccc.traineddata, который и позволит нам дальше распознавать наш загадочный новый язык.

9. Проверяем, стоило ли оно того :)
Теперь попробуем распознать наш образец с помощью уже обученного Tesseract-а:
sudo cp ccc.traineddata /usr/share/tesseract-ocr/tessdata/
tesseract ccc.tif output -l ccc
Теперь смотрим в output.txt и радуемся (или огорчаемся, в зависимости от результата).



4 комментария:

  1. Спасибо за пост-он действителььноо понятнее, чем мануал.
    Но у меня на шаге 4 ошибка: "Failed to load font_properties from ors.font_props". (ors.font_props-это Ваш ccc.font_properties, в мануале пишут что можно и так). Пробовал менять мое "aaa" на Monospase (и в *.tr, соответственно)- та же ошибка.

    Как быть и что делать с этим?
    Система-Mint17
    Спасибо.

    ОтветитьУдалить
  2. На втором шаге с pyTesseractTrainer-1.03 возникли проблемы, с бубном как не бегал, так и не запустил. С питоном практически не знаком, на компе стояла версия 3.6, ругалась на синтаксис print типа invalid sintax, после правки оказалось что используемые модули GUI pygtk используется только в старых версиях, в общем для запуска нужен питон 2.6, подыскал эту версию. Потом этот pygtk установил, но работать скрипт все равно не захотел, то ли ему не нравится Win7 x64, короче дальше я сдался... Пока делал боксы из шага 2 заметил что если предварительно хорошо обработать изображение до чистого бинарного вида, выстроить все символы в одном масштабе на одной линии - то распознаются они вполне себе и так хорошо) Пока что работаю над качеством предварительной обработки

    ОтветитьУдалить
  3. http://vietocr.sourceforge.net/training.html

    ОтветитьУдалить
  4. Аноним, спасибо.

    ОтветитьУдалить