image

Сегодня я покажу, как добавить опцию распознавания текста (OCR) в Ваше Android приложение.

Наш тестовый проект — это один единственный Activity, в который я запихнула и распознавание. Итого в общем счете всего 200 строк кода.

Важная фича — опция OCR работает offline. OCR увеличивает ваш .apk приблизительно на 17mb.

Tesseract — пожалуй, самая популярная и качественная бесплатная OCR библиотека, у которой до сих пор выходят апдейты. Создатели Tesseract — разработчики из Google.

Tesseract написан на С, но существует проект tess-two — готовый инструмент по использованию Tesseract на Android платформе. Он предоставляет Java API для доступа к изначально скомпилированным Tesseract классам. Все, что нужно — это добавить tess-two в ваш build.gradle:

dependencies {
    compile 'com.rmtheis:tess-two:5.4.1'
}

Кроме этого тессеракту потребуется .traineddata файл. Этот файл содержит данные для эффективного распознавания, словари слов и прочее. Файл уникален для каждого языка. Скачать .traineddata для любого языка можно по ссылке. Замечу, что есть возможность создать свой собственный .traineddata файл. Это может быть полезно, если вы распознаете специ��ический текст или у вас свой словарь возможных слов. Теоретически, кастомизация повысит качество распознавания.

Перед тем, как перейти к java коду, убедитесь в том, что вы положили в проект файл для английского языка eng.traideddata. Например, в src\main\assets\tessdata.

Вам потребуется сконфигурировать тессеракт, перед тем как запускать распознавание. Для этого нужно передать в метод конфигурации (init) два параметра — путь к папке tessdata на вашем Android устройстве и язык («eng»). Будьте внимательны, путь к папке tessdata, а не к .traideddata файлу, если папка будет названа иначе, код не будет работать. Очевидно, вам эту папку нужно создать на external storage и поместить в неё eng.traideddata.

Привожу метод, который из Bitmap получает распознанный текст:

import com.googlecode.tesseract.android.TessBaseAPI;
//...

private String extractText(Bitmap bitmap) throws Exception
{
	TessBaseAPI tessBaseApi = new TessBaseAPI();
	tessBaseApi.init(DATA_PATH, "eng");
	tessBaseApi.setImage(bitmap);
	String extractedText = tessBaseApi.getUTF8Text();
	tessBaseApi.end();
	return extractedText;
}

Да-да, очень просто.

Результат

image

Рекомендации

1. Лучше запускать OCR на сервер стороне. Если у вас Java проект — используйте tess4j — JNA wrapper для Tesseract. Качество распознавания выше на 20-30%. Не садит батарею, не утяжеляет .apk.

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

Исходный код доступен здесь.

На этом все.