はじめに
Tesseract-OCRはオープンソースの文字認識エンジンである。文字認識を担うライブラリとそれを用いたコマンドラインツールが提供される。C/C++APIを用いてプログラム内に組み込むことができるが、そのほか多くの言語によるラッパーも提供される。最近リリースされた最新版(4.0)には、従来の認識エンジンに加え、LSTMベースのニューラルネットワークによる認識エンジンが搭載された。今回の記事では、この最新版の導入手順と使用方法を概説する。私の環境がMacであるので、以下の説明は全てMac環境での動作事例である。
インストール手順
ビルド済みパッケージをHomebrewを用いてインストールする方法と、ソースからビルドする方法を示す。
Homebrew
以下のコマンドでインストールできる。
1 |
gt; brew install tesseract --HEAD |
--HEAD
をつけないと1つ前の3系がインストールされてしまうので注意が必要である。
Macports(ソースのコンパイル)
Macportsでインストールできるのは3系のみなので、ソースをコンパイルする必要がある。詳細な手順はこちらに記載されている。私が行った手順は以下の通り。最初に依存ライブラリを入れる。
1 2 3 4 5 |
gt; sudo port install autoconf gt; sudo port install automake gt; sudo port install libtool gt; sudo port install pkgconfig gt; sudo port install leptonica |
次に、ソースをダウンロードしコンパイルする。
1 2 3 4 5 6 |
gt; git clone https://github.com/tesseract-ocr/tesseract.git gt; cd tesseract gt; ./autogen.sh gt; ./configure gt; make gt; sudo make install |
OpenMPを組み込むこともできるが、Macのコンパイラ(clang)がオプション-fopenmp
をサポートしておらず今回は割愛した。必要であれば別のコンパイラ(gcc)を用いれば良い。
ここまでの作業で本体のインストールは完了した。コマンドラインに以下を打ち込んでみる。
1 2 3 4 5 6 7 |
gt; tesseract --version tesseract 4.0.0-31-gde37 leptonica-1.76.0 libjpeg 9c : libpng 1.6.35 : libtiff 4.0.9 : zlib 1.2.11 : libwebp 1.0.0 : libopenjp2 2.3.0 Found AVX2 Found AVX Found SSE |
訓練済みモデルの導入
Homebrewによるインストールであれば必要ない作業であるが、ソースから導入した場合は訓練済みモデルをここから別途ダウンロードする必要がある。サポートされる言語は161個である。ダウンロードしたファイルは/usr/local/share/tessdata/に置く。このディレクトリはtesseractがデフォルトで見に行く場所であるので、環境により異なるだろう。
1 2 |
gt; ls /usr/local/share/tessdata/ configs eng.traineddata jpn.traineddata pdf.ttf tessconfigs |
今回は英語(eng.traineddata)と日本語(jpn.traineddata)を用いる。
ここまでの作業でtesseractを使う準備は整った。
プログラム内での実装例
C++による実装例は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <string> #include <iostream> #include <tesseract/baseapi.h> #include <leptonica/allheaders.h> #include <opencv2/highgui.hpp> const std::string PATH = "/Users/kumada/Projects/tesseract/tesseract/tesseract/sample_jpn_2.png"; int main(int argc, const char * argv[]) { // create tesseract object auto ocr = std::make_unique<tesseract::TessBaseAPI>(); // initialize tesseract to use English (eng) and the LSTM OCR engine. // ocr->Init(nullptr, "eng", tesseract::OEM_LSTM_ONLY); ocr->Init(nullptr, "jpn", tesseract::OEM_LSTM_ONLY); // set page segmentation mode to PSM_AUTO (3) ocr->SetPageSegMode(tesseract::PSM_AUTO); // open input image using OpenCV auto im = cv::imread(PATH, cv::IMREAD_COLOR); // set image data ocr->SetImage(im.data, im.cols, im.rows, 3, static_cast<int>(im.step)); // run tesseract OCR on image auto out_text = std::unique_ptr<char[]>(ocr->GetUTF8Text()); std::cout << out_text << std::endl; // Destroy used object and release memory ocr->End(); return 0; } |
- 7行目:読み込む画像へのパス
- 11行目:OCRオブジェクトを作成
- 14行目:OCRオブジェクトを初期化。Initの第1引数には言語ファイルが存在するディレクトリへのパスを記載する。デフォルトのディレトリに格納した場合はnullptrにする。第2引数には言語ファイルの種類を記載する。第3引数には認識エンジンの種類を書く。ここではLSTMを用いたエンジンを選択した。
- 18行目:画像のレイアウト解析のためのオプションである。APIリファレンスを読んでも良くわからないが、このページが参考になる。
- 21行目:画像を読み込む。
- 24行目:OCRオブジェクトに画像を設定する。第1引数は画像データ、第2引数は画像の高さ、第3引数は画像の幅、第4引数は1画像あたりのバイト数、第5引数は画像の幅をバイト数に換算した値である。今の場合は幅に3を掛けた値になる。
- 27行目:OCRを実行する。Getの付く関数は何かを返すだけの処理にすべきである。この関数で認識処理までさせるのはどうかと思う。また、この関数はcharのポインターを返し、メモリ管理はユーザに委ねられる仕様となっている。なのでユーザ側がメモリ解放の責任を負う。std::stringで受けても良い。
- 31行目:初期化前の状態に戻す。
プログラムの実行例
使用言語をengにし、次の画像を与える(このページから切り出した画像)。
実行結果は以下の通り。
1 2 |
If you want support for multithreading, you have to install OpenMP first (see above) and tell the compiler and linker how to activate OpenMP support. This is done by adding that information to |
全文字正解。
次は手書き文字を試してみる。ここの画像を用いた。
結果は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 |
£ Gina Tremaglio graduated from Emmanuel College with A B.A. in Writing and Literature. She enjoys writing non- fiction memoir as well as children’s literature. Gina will be pursuing a Master's degree in TESOL (Teaching English to Speakers of Other Languages) and hopes fo publish a book \for English language learners. Her work has also been featured in Reverb Magazine. |
ところどころ余計な文字や行があるが、ほぼ正解。
次はこれ。ここから切り出した。
結果は以下の通り。
1 2 3 4 5 6 |
Detected 7 diacritics J managed As win om ebay arcetion Cost-uceh— >! ‘ = ¢ Aven ik Pn i of it dp Jt | Local. |
良くない。筆記体は無理なようだ。出力先頭に「Detected 7 diacritics」が出ている。diacriticとは文字の頭につく記号のこと。
次は日本語で。使用言語をjpnに変更し、以下の画像を読み込む。このページから切り出した。
結果は以下の通り。
1 2 3 4 5 |
自 社 の loT シ ス テ ム を 利 用 し た 工 場 ( 製 造 業 ) 向 け ソ リ ュ ー シ ョ ン `Orizuru」 は 、 工 場 内 の 各 種 設 備 か ら デ ー タ を 収 集 す る ` ゲ ー ト ウ ェ イ 」 、 収 集 し た デ ー タ 処 理 を す る ` デ ー タ プ ラ ッ ト フ ォ ー ム 」、 リ ア ル タ イ ム に デ ー タ を 見 え る 化 す る ` ダ ッ シ ュ ボ ー ド 」、③D CAD デ ー タ を ブ ラ ウ ザ 上 で 表 示 す る `③D ビ ュ ー」 な ど の 各 シ ス テ ム を 備 え る ト ー タ ル ソ リ ュ ー シ ョ ン に な り ま す 。 |
” 「 “が” ` “として認識されている。3Dの” 3 “も間違っている。余分な行が挿入されている。
次は青空文庫から切り出した画像。谷崎潤一郎「痴人の愛」より。
結果は以下の通り。
1 2 3 4 |
Detected 8 diacritics 私 は こ れ か ら 、 あ ま り 世 間 に 類 例 が が な い だ ろ う と 思 わ れ る 私 達 夫 婦 の 間 柄 に 就 い て 、 出 来 る だ け 正 直 に 、 ざ っ く ば ら ん に 、 有 り の ま ま の 事 実 を 書 い て 見 よ う と 思 い ま す 。 そ れ は 私 自 身 に 取 っ て 忘 れ が た な い 貫 い 記 録 で あ る と 同 時 に 、 恐 ら く は 読 者 諸 君 に 取 っ て も 、 き っ と 何 か の 参 考 資 料 と な る に 違 い な い 。 |
先頭に「Detected 8 diacritics」が出力されているが全文字正解である。
次は手書き。ここから切り出した。
結果は以下の通り。
1 2 3 4 |
te ④ Notce cu⑤ ⑦ ⑲0 . 弓 継 ②K そ も す cb で ③ ⑦ ⑦⑨ ど ⑪ の 0 ④ 格 ④ す ダ も 0 と ( か イネ ② ト レ 伝 格 ⑧⑤ ② ん か で す す 0 ・ セ も ら ⑤ ん . 日 す 誠 レ ゃ 灯 屁 し Z a⑦ よ す ど ゥ 思 膏 で す り れ ね す 、 が な り ⑨ 精 士 て テ オ ポ > ト ド 向 権 从 < す ④。 |
無理。切り出し元のページではGoodNotesなるメモアプリの紹介をしている。上の手書き文字を難なく認識している。
まとめ
今回は、文字認識エンジンTesseract-OCRを紹介した。その最新版にはLSTMベースのニューラルネットワークが搭載されている。使用事例としてC++APIを用いた実装を示し、いくつかのサンプル画像について認識結果を見た。くずれた手書き文字(例えば筆記体など)を除けば、そこそこの精度で認識できている。
今回は紹介していないが、他言語(例えばPython)による実装も可能である。また、訓練のためのライブラリも提供されている。詳細は本家のサイトを見て欲しい。
参照文献
本家以外で参照したページはここである。