Tesseract-Ocr в Visual Studio - распознаем страницу текста. Находки программиста: Обучаем Tesseract Программа для обучения tesseract

Нам нужно было улучшить документооборот в нашей компании, в первую очередь — увеличить скорость обработки бумажных документов. Для этого мы решили разработать программное решение на базе одной из OCR (optical character recognition) библиотек.

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

Кроме того, OCR используется как метод ввода информации из бумажных документов (включая финансовые записи, визитные карточки, счета-фактуры и многое другое).

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

Мы проанализировали три наиболее популярные OCR библиотеки:

— Google Text Recognition API

Google Text Recognition API

Google Text Recognition API — это процесс обнаружения текста в изображениях и видео потоках и распознавания содержащегося в нем текста. После обнаружения распознаватель определяет фактический текст в каждом блоке и разбивает его на слова и строки. Он обнаруживает текст различных языков (французский, немецкий, английский и т.д.) в режиме реального времени.

Стоит отметить, что, в целом, данная OCR с поставленной задачей справилась. Мы получили возможность распознавать текст как в real-time, так и с уже готовых изображений текстовых документов. В ходе анализа данной библиотеки мы выявили как преимущества, так и недостатки ее использования.

Преимущества:

— Возможность распознавания текста в реальном времени

— Возможность распознавания текста с изображений;

— Небольшой размер библиотеки;

— Высокая скорость распознавания.

Недостатки:

— Большой размер файлов с обученными данными (~30Mb).

Tesseract

Tesseract — это OCR библиотека с открытым исходным кодом для разных операционных систем. Представляет собой бесплатное программное обеспечение, выпущенное под лицензией Apache, версия 2.0, поддерживает различные языки.

Разработка Tesseract финансировалась компанией Google с 2006 года, время, когда она считалась одной из наиболее точных и эффективных OCR библиотек с открытым исходным кодом.

Как бы то ни было на тот момент, результатами внедрения Tesseract мы остались не сильно довольны, т.к. библиотека невероятно объемная и не позволяет распознавать текст в реальном времени.

Преимущества:

— Имеет открытый исходный код;

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

Недостатки:

— Недостаточная точность распознавания, что устраняется путем тренировки и обучения алгоритма распознавания;

— Для распознавания текста в реальном времени требуется дополнительная обработка полученного изображения;

— Небольшая точность распознавания при использовании стандартных файлов с данными о шрифтах, словах и символах.

Anyline

Anyline предоставляет многоплатформенный SDK, который позволяет разработчикам легко интегрировать функции OCR в приложения. Данная OCR библиотека привлекла нас многочисленными возможностями настройки параметров распознавания и предоставляемыми моделями для решения конкретных прикладных задач. Стоит отметить, что библиотека платная и предназначена для коммерческого использования.

Преимущества:

— Довольно простая настройка распознавания нужных шрифтов;

— Распознавание текста в реальном времени;

— Легкая и удобная настройка параметров распознавания;

— Библиотека может распознавать штрихкоды и QR-коды;

— Предоставляет готовые модули для решения разных задач.

Недостатки:

— Невысокая скорость распознавания;

— Для получения удовлетворительных результатов требуется первоначальная настройка шрифтов для распознавания.

В ходе проведенного анализа для решения наших задач была мы остановились на Google Text Recognition API, которая совмещает в себе высокую скорость работы, легкую настройку и высокие результаты распознавания.

Разработанное нами решение позволяет сканировать бумажные документы, автоматически оцифровывать их и сохранять в единую базу данных. Качество распознаваемой информации составляет около 97%, что является очень хорошим результатом.

За счет внедрения разработанной системы внутренний (включая обработку документов, их создание и обмен между отделами и др.) был ускорен на 15%.

Понадобилось мне получить значения забитмапленных чисел. Числа грабились с экрана.

Я подумал, а не попробовать ли мне OCR? Попробовал Tesseract .

Ниже я расскажу как я пытался приспособить Tesseract, зачем я его тренировал, и что из этого получилось. В проекте на гитхабе лежит cmd-скрипт, автоматизирующий насколько возможно процесс тренировки, и данные, на которых я проводил тренировку. Словом, есть все что нужно, чтобы с места в карьер обучить Tesseract чему-нибудь полезному.

Подготовка

Клонируем репозитарий или скачиваем zip-архив (~6Mb). Устанавливаем tesseract 3.01 с оф.сайта . Если его там уже нет, то из подкаталога zip-архив/distros.

Переходим в папку samples, запускаем montage_all.cmd
Этот скрипт создаст итоговое изображение samples/total.png , можно скрипт не запускать, т.к. я уже поместил его в корневую папку проекта.

Зачем тренировать?

Быть может и без тренировки результат будет хороший? Проверим.
./exp1 - as is> tesseract ../total.png total

Поместим исправленный результат в файл model_total.txt , чтобы сравнивать с ним результаты распознаваний. Звездочка маркирует неправильные значения.

model_total.txt Распознавание
по умолчанию
27
33
39
625.05
9
163
1,740.10
15
36
45
72
324
468
93
453
1,200.10
80.10
152.25
158.25
176.07
97.50
170.62
54
102
162
78
136.50
443.62
633.74
24
1,579.73
1,576.73
332.23
957.69
954.69
963.68
1,441.02
1,635.34
50
76
168
21
48
30
42
108
126
144
114
462
378
522
60
240
246
459.69
456.69
198
61
255
27
33
39
525 05*
9
153*
1,740 10*
15
35*
45
72
324
455*
93
453
1,200 10*
50 10*
152 25*
155 25*
175 07*
97 50*
170 52*
54
102
152*
75*
135 50*
443 52*
533 74*
24
1,579 73*
1,575 73*
332 23*
957 59*
954 59*
953 55*
1,441 02*
1,535 34*
50
75*
155*
21
45*
30
42
105*
125*
144
114
452*
375*
522
50*
240
245*
459 59*
455 59*
195*
51*
255

ошибки распознавания по умолчанию

Видно, что ошибок много. Если приглядеться, то можно заметить, что не распознается десятичная точка, цифры 6 и 8 распознаются как 5. Поможет ли тренировка избавиться от ошибок?

Тренировка

Тренировка tesseract позволяет натаскать его на распознавание изображений текстов в том виде, в котором вы будете скармливать ему аналогичные изображения в процессе распознавания.
Вы передаете tesseract тренировочные изображения, исправляете ошибки распознавания и передаете эти правки tesseract-у. А он корректирует коэффиценты в своих алгоритмах, чтобы впредь не допускать найденных вами ошибок.

Чтобы выполнить тренировку надо запустить./exp2 - trained> train.cmd

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

Результаты этой работы записывает в файл total.box, который выглядит так:
2 46 946 52 956 0
7 54 946 60 956 0
3 46 930 52 940 0
3 54 930 60 940 0
3 46 914 52 924 0
9 53 914 60 924 0
6 31 898 38 908 0
2 40 898 46 908 0
5 48 898 54 908 0
0 59 898 66 908 0

Здесь в певом столбце символ, а в 2 - 5 столбцах координаты левого нижнего угла прямоугольника, его высота и ширина.

Конечно редактировать его вручную сложно и неудобно, поэтому энтузиастами были созданы графические утилиты, облегчающие эту работу. Я воспользовался , написанной на JAVA.

После запуска./exp2 - trained> java -jar jTessBoxEditor-0.6jTessBoxEditor.jar надо открыть файл./exp2 - trained/total.png , при этом будет автоматически открыт файл./exp2 - trained/total.box и определенные в нем прямоугольники будут наложены на тренировочное изображение.

В левой части приведено содержимое файла total.box, справа расположено тренировочное изображение. Над изображением расположена активная строка файла total.box

Синим изображены боксы, а красным - бокс, соответствующий активной строке.

Я исправил все неправильные 5-ки на правильные 6-ки и 8-ки, добавил строки с определениями всех десятичных точек, имеющихся в файле и сохранил total.box

После завершения редактирования надо, чтобы скрипт продолжил работу, надо закрыть jTessBoxEditor. Далее все действия выполняются скриптом автоматически без участия пользователя. Скрипт записывает результаты обучения под кодом ttn

Чтобы использовать результаты обучения при распознавании надо запустить tesseract c ключом -l ttn
./exp2 - trained/> tesseract ../total.png total-trained -l ttn

Видно, что все цифры стали распознаваться правильно, однако десятичная точка по-прежнему никак не распознается.

model_total.txt Распознавание
по умолчанию
Распознавание
после тренировки
27
33
39
625.05
9
163
1,740.10
15
36
45
72
324
468
93
453
1,200.10
80.10
152.25
158.25
176.07
97.50
170.62
54
102
162
78
136.50
443.62
633.74
24
1,579.73
1,576.73
332.23
957.69
954.69
963.68
1,441.02
1,635.34
50
76
168
21
48
30
42
108
126
144
114
462
378
522
60
240
246
459.69
456.69
198
61
255
27
33
39
525 05*
9
153*
1,740 10*
15
35*
45
72
324
455*
93
453
1,200 10*
50 10*
152 25*
155 25*
175 07*
97 50*
170 52*
54
102
152*
75*
135 50*
443 52*
533 74*
24
1,579 73*
1,575 73*
332 23*
957 59*
954 59*
953 55*
1,441 02*
1,535 34*
50
75*
155*
21
45*
30
42
105*
125*
144
114
452*
375*
522
50*
240
245*
459 59*
455 59*
195*
51*
255
27
33
39
625 05*
9
163
1,740 10*
15
36
45
72
324
468
93
453
1,200 10*
80 10*
152 25*
158 25*
176 07*
97 50*
170 62*
54
102
162
78
136 50*
443 62*
633 74*
24
1,579 73*
1,576 73*
332 23*
957 69*
954 69*
963 68*
1,441 02*
1,635 34*
50
76
168
21
48
30
42
108
126
144
114
462
378
522
60
240
246
459 69*
456 69*
198
61
255

ошибки распознавания с обучением

Увеличение изображения

Увеличивать можно по-разному, я попробовал два способа: scale и resize

total-scaled.png (фрагмент) total-resized.png (фрагмент)
convert total.png total-scaled.png -scale "208x1920" convert total.png total-resized.png -resize "208x1920"

Так как изображения символов увеличились вместе с самими изображениями, данные тренировки под кодом ttn устарели. Поэтому дальше я распознавал без ключа -l ttn.

Видно, что на изображении total-scaled.png tesseract путает 7-ку с 2-кой, а на total-resized.png не путает. На обоих изображениях корректно определяется десятичная точка. Распознавание изображения total-resized.png почти идеально. Есть только три ошибки - пробел между цифрами в числах 21, 114 и 61.

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

ошибки распознавания total-scaled.png

ошибки распознавания total-resized.png

model_total.txt Распознавание
по умолчанию
Распознавание
после тренировки
total-scaled.png total-resized.png
27
33
39
625.05
9
163
1,740.10
15
36
45
72
324
468
93
453
1,200.10
80.10
152.25
158.25
176.07
97.50
170.62
54
102
162
78
136.50
443.62
633.74
24
1,579.73
1,576.73
332.23
957.69
954.69
963.68
1,441.02
1,635.34
50
76
168
21
48
30
42
108
126
144
114
462
378
522
60
240
246
459.69
456.69
198
61
255
27
33
39
525 05*
9
153*
1,740 10*
15
35*
45
72
324
455*
93
453
1,200 10*
50 10*
152 25*
155 25*
175 07*
97 50*
170 52*
54
102
152*
75*
135 50*
443 52*
533 74*
24
1,579 73*
1,575 73*
332 23*
957 59*
954 59*
953 55*
1,441 02*
1,535 34*
50
75*
155*
21
45*
30
42
105*
125*
144
114
452*
375*
522
50*
240
245*
459 59*
455 59*
195*
51*
255
27
33
39
625 05*
9
163
1,740 10*
15
36
45
72
324
468
93
453
1,200 10*
80 10*
152 25*
158 25*
176 07*
97 50*
170 62*
54
102
162
78
136 50*
443 62*
633 74*
24
1,579 73*
1,576 73*
332 23*
957 69*
954 69*
963 68*
1,441 02*
1,635 34*
50
76
168
21
48
30
42
108
126
144
114
462
378
522
60
240
246
459 69*
456 69*
198
61
255
22*
33
39
625.05
9
163
1,240.10*
15
36
45
22*
324
468
93
453
1,200.10
80.10
152.25
158.25
126.02*
92.50*
120.62*
54
102
162
28*
136.50
443.62
633.24*
24
1,529.23*
1,526.23*
332.23
952.69*
954.69
963.68
1,441.02
1,635.34
50
26*
168
2 1*
48
30
42
108
126
144
1 14*
462
328*
522
60
240
246
459.69
456.69
198
6 1*
255
27
33
39
625.05
9
163
1,740.10
15
36
45
72
324
468
93
453
1,200.10
80.10
152.25
158.25
176.07
97.50
170.62
54
102
162
78
136.50
443.62
633.74
24
1,579.73
1,576.73
332.23
957.69
954.69
963.68
1,441.02
1,635.34
50
76
168
2 1*
48
30
42
108
126
144
1 14*
462
378
522
60
240
246
459.69
456.69
198
6 1*
255

Оцифровка изображений по одному

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

Пробую по одному.
./exp5 - one by one> for /r %i in (*.png) do tesseract "%i" "%i"
Двух и трехзначные числа не определяются вовсе!

625.05
1740.10

Оцифровка небольшими пакетами

А если требуется оцифровывать изображения пакетами по несколько изображений (6 или 10 в пакете)? Пробую по десять.
./exp6 - ten in line> tesseract teninline.png teninline

Распознаются, и даже без пробела в числе 61.

Выводы

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

Предварительная обработка изображения имеет больший эффект, чем обучение. Увеличивайте со сглаживанием: convert -resize…

Распознавание отдельно стоящих «коротких» двух и трехзначных чисел неудовлетворительно - числа надо собирать в пакеты.

Но в целом tesseract почти идеально справился с задачей, несмотря на то, что он заточен под другие задачи - распознавание надписей на фото и видео, сканах документов.

Если есть готовые решения, нет смысла изобретать костыли и велосипеды. С особым цинизмом это утверждение доказали авторы криптолокера, который для своих целей пользовался CryptoAPI:). Справедливо оно и для решения нашей сегодняшней задачи - расшифровки капчи (с образовательными целями, разумеется). Вперед, запускаем Visual Studio!

Вступление

Весь процесс предстоящей работы можно условно поделить на несколько этапов:

  • скачать картинки;
  • убрать шумы и другие искусственные искажения;
  • выделить области связанности (символы), сохранить их;
  • обучить нейросеть или создать словарь;
  • распознать.

В этом нам помогут:

  • AForgeNet - библиотеки компьютерного зрения и искусственного интеллекта;
  • Tesseract - программа для распознавания текстов;
  • Fanndotnetwrapper - обертка.NET нейросети FANN;
  • алгоритм поиска связанности CCLA от Omar Gameel Salem.

Исходник на dvd.сайт

Не забудь скачать сабж, он пригодится тебе при прочтении этой статьи. Никакой малвари, никакого экстремизма - только чистая наука, только OCR-технологии, только хардкор!

Подготовительный этап

Запускаем Visual Studio и создаем новый оконный проект на языке C#. Откроем его в проводнике, для того чтобы скопировать туда требуемые файлы.


Для обучения нейросети FANN использована часть кода из Tesseract, отличие заключается в том, что мы создаем один текстовый файл train.tr, в котором первая строка - количество картинок, количество точек в каждой (ширина, умноженная на высоту) и количество выходов (букв, которые мы ищем). Сама картинка до всего этого проходит обязательную бинаризацию, для того чтобы выделить всего два состояния каждой точки (1 - черный, 0 - белый цвет), и сохраняется далее в этом же файле во всех следующих строках. Для удобства и возможности использовать разные заранее созданные обученные ann-файлы был создан дополнительный текстовый файл CONFIG.txt. Он состоит из одной строки и указывает количество точек и выходов с их значениями, случайно запустить проверку captcha на другом ann-файле не получится.

String a = File.ReadAllText(SaveFilesPath + "CONFIG.txt"); string b = a.Split(" "); int SumPix = Convert.ToInt32(b); int Outpt = Convert.ToInt32(b.Length); uint layers = { (uint)SumPix, (uint)layerS, (uint)Outpt }; net.CreateStandardArray(layers); net.RandomizeWeights(-0.1, 0.1); net.SetLearningRate(0.7f); TrainingData data = new TrainingData(); data.ReadTrainFromFile(SaveFilesPath + "train.tr"); net.TrainOnData(data, 1000, 0, 0.001f); net.Save(SaveFilesPath + "FANNLearning.ann");

Получаем конфиг, читаем параметры, число слоев (layers) по рекомендации Википедии задано равным 120, все остальное было выбрано случайным образом или подсмотрено в Сети. Скорость обучения зависит от мощности твоего железа и того, что написано выше. Например, i7-4702MQ при 6500 картинок одним ядром был занят минут 20–30.

Шаг шестой. Распознавание

В заключительном этапе реализовано два подхода, но используется тот, обучение которого было проведено. Tesseract 3.02 и FANN находятся в нижней левой части главного окна. Первый умеет искать по английскому (выбираем символы из выпадающего списка), русскому, Math и словарю пользователя. Поиск словаря происходит автоматически, и в подсказке tooltip высвечиваются все доступные. Второй распознает текст по кнопке FANNOCR и выводит в лог (левая часть окна) результат анализа для каждого выбранного символа. Очень удобно смотреть, почему нейронная сеть выбрала тот или иной выход. Рассмотрим, как это работает в случае нейронной сети.

Private string OCR(Bitmap img) { ... { int whx = img.Width * img.Height; if (SUMMPIX != whx) { /* Выводим ошибку, не сошлось количество пикселей */} double input = GetPix(img); double result = net.Run(input); if (tempanswer.Length != result.Length) { /* Выводим ошибку, разное количество выходов */} int maxN = FindMax(result); answer = Convert.ToString(tempanswer); if (ToLogEvent != null) ToLogEvent(result, tempanswer, answer); ... } }

Получили картинку от public-метода, где реализован net.CreateFromFile(SaveFilesPath + "FANNLearning.ann") и чтение конфиг файла, tempanswer - это переменная, равная b, в ней перечислены буквы, которые мы ищем. Сравниваем число пикселей, записываем их в массив и прогоняем через обученный ann, выискивая максимально высокий процент совпадения, затем направляем результат в событие, выбрав один выход и получив букву, закрепленную за ним.

Обсуждаем результаты

Мои результаты тестирования сильно зависели от количества и качества картинок для обучения, а в случае с нейросетью FANN - и от количества выходов тоже. В среднем captcha, поддавшаяся фильтрам, имела ~80% правильного распознавания, тут многое зависит от усидчивости и желания - чему научишь, то и получишь. Главное - это работает.

Заключение

Все описанное в статье можно применить для решения многих других задач. Например, мне при поиске информации для статьи повстречался подробный разбор распознавания образа автомобиля на стоянке. Включай фантазию и Visual Studio! 🙂



Просмотров