16bitパソコン時代からOCRは存在しますが、最近の流行りは、なんといってもスマホアプリや Webサイトとの連動でしょう。例えばiPhoneアプリで、家計簿ソフトでレシートを自動読み込み できるものが幾つか販売されているようです。
これを自分でもやりたいと思ったとき.....Googleが公開しているOCRエンジンtesseract-ocrを 組み込むのがもっとも簡単.....ですが、なぜか 日本語の説明が壊滅的に足りないような 。 あっても一旦画像ファイルに書き出してからProcessPages関数で処理する例がほとんどみたい。
しかし、前述のようなスマホ組み込みでは、カメラなどからフレームバッファに読み込み、 所望の画像処理をしてからOCRにかける方法が一般的で、いちいちファイルに書いてなど いられない。また、プリ処理として他の画像処理ライブラリ(例えばOpenCV)と組み合わせることも 十分考えられるでしょう。
そこで(手前味噌ながら)メモリ渡しのサンプルをかいてみた、という記事です。
先にライブラリのインストールを。私が使っているDebian squeeze(古い)では、 tesseractのコンパイルに必要なleptonicaが古くてコンパイルできなかったので ソースでインスコした。
まず leptonica-1.69 を落としてきて
# tar xvzf leptonica-1.69.tar.gz # cd leptonica-1.69 # ./configure # make # make install
でおしまい。次にtesseract-ocr本体を http://code.google.com/p/tesseract-ocr/downloads/listから落としてくる。 必要なのは以下の3つ。
* tesseract-ocr-3.02.02.tar.gz * tesseract-ocr-3.02.eng.tar.gz * tesseract-ocr-3.02.jpn.tar.gz
コンパイルは以下。デフォルトのトレーニングデータは/usr/local/shareにコピーしている。
# tar xvzf tesseract-ocr-3.02.eng.tar.gz # tar xvzf tesseract-ocr-3.02.jpn.tar.gz # cp -dpR tesseract-ocr/tessdata /usr/local/share # tar xvzf tesseract-ocr-3.02.02.tar.gz # cd tesseract-ocr # ./configure # make # make install
ソースコードをコンパイルする(makeかけよ)。
% g++ ocr1.cpp -o ocr1 -I/usr/local/include -L/usr/local/lib -lopencv_core -lopencv_objdetect -lopencv_imgproc -llept -ltesseract -lstdc++
コマンドライン引数は入力画像リスト(テキストファイル)を1個だけとる。
usage: ./ocr1 [file_list]
中身は(ファイル名)(改行)という書式のテキスト。 ここでは画像が入ったディレクトリtest4からfindコマンドで作ろう。
% find ./test4 -type f -name "*.jpg" | sort > test4.txt % ./ocr1 ./test4.txt
そのうちの1つの画像。
ocr1では内部でOpenCVを用いて2値化する。
tessarectで認識させてみると....
令頁収 書 20ー3 黛 03 月 23 日 繝囗2 メ” タ一寶運賃 \ーー'0閃門 遠昆巨離 閤]弓` 〝一 \2ーD円 固定迎車来邦金 ~ト \3m 円 運賃寧斗金言十 \ーー'ー5ロ 円 ETC 料金 + \2印円 合害十 \工ー' 40。円 現 金 支麦ム \ーー'400円 車董両番号 皿2732 毎度こ~乗車ぁ'」ヵヾとうこ〝さし`ます〝 お忘れ物鸞ま当ネ土ヘ +丶 日興自動車蠅(株〉 丁EL 03-3g62ー8Bgー ご要望L藪当ネ士又縄ま (貴オ)東京夕クシ'セン夕ー TEL 03ー3648ーD300
うーん.....
画像の水平をとったり、コントラストを変えたり、tesseractのAUTOレイアウトを使わずに、 自前で文字のblobをとったりすると、もう少し精度があがると思われる。
で、メモリ読み込みのサンプルといいつつファイルから読み込んでいるように見えますが.... ソースコード的な味噌は以下の箇所です。
/* 8bit2値画像をポインタ渡し */ Size ss = small_img.size(); api.SetImage((uchar*)small_img.data, ss.width, ss.height, small_img.channels(), small_img.step1()); /* OCR認識 */ api.Recognize(0);
tesseractAPIに渡しているのはOpenCVのMatの生イメージの情報(縦横ビット震度)だけで、 データ自体はポインタ渡しで良いという訳。OpenCVはffmpegやリアルタイムのカメラ認識も できるので、いろいろ応用が効きそうですね。
Before...
_ 通りすがり [うん、足りないねぇwwww]
_ 通りすがりのあいあん [足りませんなあ(笑)]
_ ぱ [がびーん]