AndroidでOCRをする時に便利なtess-twoライブラリ

2019年3月29日

あることをしたくて、カメラ画像から文字の読み込みをしてみました。一般的にOCRと呼ばれる技術ですが、Androidのカメラで撮影した画像から文字を読み込む場合はどうすれば良いのでしょうか。

欲しい機能は、フリーのライブラリであること、文字変換が高速であるという2点です。フリーのライブラリを探すと「tess-two」というライブラリが見つかりました。このライブラリを使用してみます。

今回は、要所のみのソースになることをご了承ください。実は、AR-J-GPSに組み込んでカメラ画像から文字を取得してテストをしています。

1.tess-twoライブラリのダウンロード

tess-twoは、GitHubからソース一式をダウンロードできます。

https://github.com/rmtheis/tess-two

また、読み取る文字用のOCR言語データが必要です。

https://github.com/tesseract-ocr/tessdata/tree/3.04.00

各国のOCR言語データがありますが、日本語をダウンロードします。

jpn.traineddata

が日本語に該当します。

2.セットアップ

build.gradleにtess-twoを追加

プロジェクトにtess-twoを組み込むには、ダウンロードしたソースを手動で組み込む必要はなく、build.gradleのdependenciesに以下の記述を追加します。

implementation 'com.rmtheis:tess-two:9.1.0’

なお、tess-twoのライブラリは順次バージョンアップされているので、GitHubのページに記述されているものを使用してください。

※正規プロジェクトにおけるバージョンアップは終了したようです

OCR言語データをセットする

アプリケーションに用意されるfilesフォルダに、OCR言語データを置きます。

files/tessdata/jpn.traineddata

これはあくまでもテストであり、assetsにOCR言語データを置いて、filesフォルダにコピーするのが正しいやり方です。

3.プログラム

それでは、プログラミングします。

tess-twoのインスタンスを作成する

tess-twoのインスタンスを作成します。そして、init関数で初期化します。

private TessBaseAPI tessBaseAPI ;

// OnCreateでインスタンスを作成する
tessBaseAPI = new TessBaseAPI();
tessBaseAPI.init(getFilesDir(), "jpn");

元になるビットマップ画像を用意する

文字を読み取る画像をビットマップで用意します。それぞれ3通りでテストしました。

// ①
Bitmap ocrBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 

// ②
Bitmap ocrBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ocrtest2);

// ③
Bitmap ocrBitmap = BitmapFactory.decodeFile(imgpath) ;

①は、カメラで撮った画像(jpeg)をビットマップに変換しました。②は、drawableに画像を置いて読み込みました。③は画像ファイルをパスを指定して読み込みました。①が目的の方法ですが、②や③を使うプログラムもあるでしょう。

文字読み取りの実行

tess-twoにビットマップを渡して文字を取得します。

tessBaseAPI.setImage(ocrBitmap);
String getstr = tessBaseAPI.getUTF8Text();

getstrに読み込んだ文字が入ります。

4.実行結果

AR-J-GPSのカメラで撮った写真や、Androidのキャプチャー画像などから文字を読み込んでみました。

スマートフォンのキャプチャー画面から文字取得

さっぽろ周辺マップの画面をキャプチャーした画像から文字を取得します。

”地図移動”の文字が取得できていませんが、それ以降の文字は取得できています。”地図移動”の部分は反転文字なので、認識できなかったようです。ハードコピーであれば、変換効率は良さそうです。

カメラ画像から文字取得

カメラ画像からの文字の読み込みは、精度がイマイチです。

全体的に文字が小さく、暗く鮮明でないことも災いしてか、変換成績が良くありません。アルファベット部分の変換もできないわけではないはずですが、ほぼ失敗しています。アルファベット部分は、英語のOCRデータを使って変換させるなどの対策が合った方が良いでしょう。

そして一番の問題は、判定に時間が掛かることです。実はカメラ画像は縮小しています。カメラ画像を縮小せずに変換すると、フリーズしたと勘違いするほど変換に時間が掛かります。また、画像を縮小して変換しても、画像の程度にも寄りますが時間が掛かります。

個人的にはリアルタイムで次々に文字を取得したかったので、これでは少し厳しいです。

5.まとめ

期待した文字変換ですが、ちょっと期待はずれと言った感じです。OCR機能に関しては、これからもテストして行こうと思います。英語のOCR文字データを使った場合はどうなのかを今後検証し、リライトする予定です。

6.その後のテスト1

その後も、いろいろテストしています。画像サイズを変えてみたり、モノクロ画像にしてみたりとやっていますが、期待した結果はまだ得られていません。直近のテストは以下のようになりました。

このようなテキスト文書を印刷して、カメラで撮影して文字を取得してみます。印刷すると

この印刷文書をOCR変換してみます。

やはり今一つの変換です。特に、アンダーバーがあったり、カーソルがあったりすると誤認識していいます。

そこで、playストアで人気の「テキストスキャナー」というソフトでOCR変換してみます。

これは素晴らしい変換です。ほぼ誤変換がありません。認識エンジンがすごいだけでなく、前後の文章から正しい文字を導きだしているようです。これはサーバー側でも判断しているようで、tess-twoのようにローカルで判断するよりも正解率がずっと高いのだと思います(あくまでも推測)

純粋なOCRソフトウェアを作るなら、自分でOCRソフトを作るまでもなく、「テキストスキャナー」を使うと良いですね。

テキストスキャナー [OCR 日本語対応] ※Playストアへ移動します