プログラミングとか日常とかの覚書っぽいなにか
× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
いろいろと手当たり次第に試しているような気もする今日この頃。
OCR(光学文字認識)の機能を実現できないものかと思い立ち、フリーのOCRライブラリがないか探してみたところ、『Tesseract OCR』(テッサラクトOCR)なるものがあることを知ったので、これを試してみることにしました。 どうやらTesseract OCRのライブラリ自体はC++で書かれているようなのですが、ライブラリのビルド方法や自作アプリからの使用方法、各クラスや関数の説明などが少なく、分からないことが山積みで、Google先生の力を借りて検索してても日本語ドキュメントどころか英語の範囲でもなかなか見つからずに試行錯誤する羽目になりました。 今回のテストプログラムを作成するまでの過程を以下にまとめておきます。 Tesseractライブラリのビルド まずはTesseract OCRのプロジェクトページからライブラリのソースなどをダウンロードします。Google Project Hostingで管理されており、以下のページからダウンロードできます。 tesseract-ocr - Google Project Hosting http://code.google.com/p/tesseract-ocr/ ダウンロードリスト http://code.google.com/p/tesseract-ocr/downloads/list 現時点の最新リリースバージョンはVer.3.01なので、*-3.01.* という名前のファイルが必要になります。今回は、以下の3つが必要となるので、ダウンロードしてきます。
上記3つのうち2つはアーカイブの形式が ~.tar.gz なので、対応する圧縮・解凍ソフトを使って展開してください。 ソースファイルには、ライブラリをビルドするためのVisual C++のプロジェクトファイルは含まれていないので、別にダウンロードする必要があります。これらの2つはどちらも「tesseract-3.01」フォルダを起点として、その下にファイルやサブフォルダがあるので、1つにまとめておきます。 ソースには言語データファイルが含まれていないので、これもまた別にダウンロードする必要があります。今回は英語のものを使います。こちらは「tesseract-ocr」フォルダの下に「tessdata」サブフォルダがあって、その中に各種データファイル(eng.*** という名前)がありますので、これらのファイルをソースの「tessdata」フォルダの中にコピーしておきます。 (今回はライブラリのみビルドするのでこの位置に置かなくても大丈夫なのですが、ソリューション全体をビルドする場合にはこの位置にないとビルド時にエラーが発生してしまうみたいです。) Visual C++のソリューションファイル・プロジェクトファイルはVisual C++ 2008 用のものとVisual C++ 2010 用のものがあり、それぞれ「vs2008」と「vs2010」フォルダに格納されています。使っている開発ツールに合った方を使うようにします。私の環境はVisual Studio 2010がインストールされているので、Visual C++ 2010用の方を使っていきます。(ただし、Visual Studio 2010を使う場合でも、一部のファイル(.libなど)はvs2008フォルダの中のものが使用されます。) ソースファイルには、Tesseractライブラリ内で使用されている各種ライブラリ群、コマンドライン版Tesseract OCRアプリケーションや、関連するツールなどのソースが含まれているので、ソリューションファイル内にも数多くのプロジェクトが存在します。今回はOCRライブラリのみを必要としているので、「libtesseract」プロジェクトのみビルドするようにします。 このソリューションファイルにはビルドの構成として以下の4つの構成があります。
ただ、少なくともVisual C++ 2010の環境では、「Debug」「Debug.dll」の構成は使用できなさそうです。というのも、Tesseractライブラリでは内部でLeptonicaと呼ばれる画像処理ライブラリを使用しているのですが、これのデバッグビルド版ライブラリがVisual C++ 2008のデバッグ版ランタイムを必要としているのです。このデバッグ版C/C++ランタイムはVisual C++ 2008がインストールされた開発環境にしか存在しないはずのものなので、Visual C++ 2010の開発環境では使えないわけです。 この問題は、すでにビルドされた状態のLeptonicaライブラリを使用しているために起こる問題で、Leptonicaライブラリも含めてソースからビルドしなおせばこの問題は発生しないわけですが…。 一方、リリースビルドの方であれば、実行環境にVisual C++ 2008ランタイムライブラリがインストールされていれば問題なく実行できます。ここでは、ツールバーにあるビルド構成で「Release」を選択してビルドを行います。 ソリューションエクスプローラ上の「libtesseract」を右クリックして表示されるメニューでビルドを選択し、Tesseractライブラリをビルドします。(プロジェクトの依存関係が適切に設定されているので、必要となる他のプロジェクトについても自動的にビルドされます。) ビルド後に「tesseract-3.01\vs2010\Release」フォルダに「libtesseract.lib」が格納されていれば成功です。 お試しプログラムの作成 次に、Tesseractライブラリを使ったお試しプログラムを作っていきます。 Web上ではTesseractを使ったソースのサンプルがほとんど見当たりませんでした…。 そのため、「api\baseapi.h」に書かれているコメントや、一緒に含まれているコマンドラインツールのソース「api\tesseractmain.cpp」を読み解いて書いていくことになると思います。(Doxygenで作られたドキュメントはダウンロード可能なんですけど…うーん…) その結果出来上がったお試しプログラムは以下の通り。「tesseractmain.cpp」を簡略化したものになっています。ビットマップファイル input.bmp を読み込み、文字列をコンソールに出力するようにしています。
TessBaseAPIクラスがTessseractライブラリの基本的なAPIを提供するクラスのようです。クラスや定数名などはtesseract名前空間に含まれている模様。また、文字列を表す STRING 型が存在するらしい…。 Tessseract::Init() の第1引数は、言語データファイル(今回は eng.traineddata)を含むtestdataフォルダの親フォルダのパスを指定する必要があります。この引数は最後の文字がファイルパスのデリミタ(スラッシュ「/」とかバックスラッシュ「\」)であると想定されていますが、もし最後の文字がデリミタでない場合は、最後のデリミタより後ろが切り捨てられるようです。 main() の引数 argv[0] は通常exeファイルのフルパスが指定されているので、これをそのまま指定することでexeファイルがあるフォルダを指定したことになります。したがって、実行時にはexeのあるフォルダに「testdata」フォルダを作成し、その下に言語データファイル eng.traineddata を格納しておく必要があります。 tessBaseApi.Init() にはもっと多くの引数をとるオーバーロードが存在するようですが、それを調べる時間がなかったので、それについては後日に後回し。 お試しプログラムのビルドを行うのですが、今回はVisual C++のIDEでなく、makefile を作成してMAKEツールでビルドする方法を取りました。なんとなくそちらの方がラクかなーと思ったので…。(makefileの雛型がすでに手元にあったというのもありますが。) makefileは以下の通り。テストプログラムのソースを test.cpp として保存し、それと同じフォルダにファイル名「makefile」を作成し、以下の内容で保存します。ただし、Tesseractライブラリのパス(「TESS_BASE = XXX」の部分)については、上記のライブラリビルド時のフォルダに直してください。また、Visual C++ 2010でなくVisual C++ 2008を使っている場合は、「vs2010」の部分を「vs2008」に直す必要があるので注意。
Visual C++のコマンドプロンプトを実行し、cdコマンドでソースおよびmakefileのあるフォルダに移動します。以下のように nmake (Visual C++のMAKEツール)を実行すると、お試しプログラムのビルドを行います。
うまくビルドが完了すれば、test.exe が出来上がっているはずです。 ビルドができたら、同じフォルダ配下に「testdata」フォルダを作成して言語データ eng.traineddata をコピーします。 さて、ビットマップファイルとして、以下のような画像を「input.bmp」という名前で同じフォルダに置いて実行してみました。(これはTesseract OCRのプロジェクトページの一部をキャプチャし、切り出してきてビットマップファイルとして保存したものです。) そして、コマンドプロンプトから test.exe を実行して出てきた出力は以下の通り。 result: [A||OCRE||gnel7|atwasdevel0pedatHPLahsl>e\weev|l986a|dl995 mammasmge ] あ、あれ…? ところどころ合ってるように見えなくもないけど…。もしかしたら文字が小さすぎたのかも? ブラウザの表示で文字を大きめにして再度キャプチャし、以下の画像で再挑戦。 実行して出てきたのは以下の通り。 result: [An OCR Engine that was developed al HP Labs belween 1985 and 1995 and now at Google ] まだ一部おかしいところは残っているものの(「at」が「al」になっているなど)、それなりにちゃんと読めているようです。 時間があれば、もうちょっと調べていきたいところです。 IDEでビルドする場合の注意 もしVisual C++のIDEでお試しプログラムのプロジェクトを作成してビルドする場合は、上記のmakefileの内容を参考に、追加のincludeディレクトリや追加のライブラリディレクトリ、追加の依存ファイルを指定する必要があります。 また、TesseractライブラリはWindows以外のOSでビルドされることも想定しており、Windowsでビルドする場合にはプリプロセッサマクロ「__MSW32__」を定義しなければならないことに注意してください(上記のmakefileでは「/D__MSW32__」コンパイルオプションが該当)。 ただし、(上記の方法のダウンロードではなく、)Subversionリポジトリから最新のリビジョンのソースを取ってきている場合は __MSW32__ マクロを定義する必要はありません。リビジョン677にて __MSW32__ ではなく _WIN32 (Visual C++コンパイラで自動的に定義されるマクロ) を参照するように修正されている模様です。(Subversionから取ってくる場合はLeptonicaライブラリも別に取ってくる必要があったりして何かと面倒そうではあるのですが。) 現在の最新リリースであるVer.3.01はリビジョン636に相当するので、Ver.3.01では __MSW32__ マクロを定義しておく必要があります。 参考 Tesseract OCRに触ってみた - takminの書きっぱなし備忘録 http://d.hatena.ne.jp/takmin/20110720/1311176261 PR
無題
「その結果出来上がったお試しプログラムは以下の通り。「tesseractmain.cpp」を簡略化したものになっています。ビットマップファイル input.bmp を読み込み、文字列をコンソールに出力するようにしています。」
のところとその下のソースをVisual2010C++でどうやって組み込みますか?親フォルダは何のフォルダですか?自分はTessdataに入れましたが。 Re:無題
ここで作成されたお試しプログラムでは、コマンドプロンプトのパラメータにファイル名を指定します。
test.exe と同じフォルダに input.bmp を置いて、以下のようにパラメータに渡します。 D:\dev\tesseracttest> test.exe input.bmp または、完全パスでも指定可能です。 D:\dev\tesseracttest> test.exe D:\dev\tesseracttest\input.bmp
無題
ご返答ありがとうございます。まだ理解不足ですみませんが、以下の質問の返答をお願いします。
#include <iostream> #include "baseapi.h" #include "strngs.h" int main(int argc, char* argv[]) { tesseract::TessBaseAPI tessBaseApi; tessBaseApi.Init( argv[0], // データパス (tessdata の親ディレクトリ名) "eng"); // 言語 "eng", "jpn" など STRING output; bool success = tessBaseApi.ProcessPages( "input.bmp", // 入力ファイル名 NULL, // リトライconfigファイル名 0, // タイムアウト値(msec) (0 は指定なし) &output); // 出力文字列 if (!success) { std::cout << "Error occurred.\n"; } else { std::cout << "result: [" << output.string() << "]\n"; } return success ? 0 : 1; } 上記のソースは。「tesseractmain.cpp」を簡略化と言いますが、つまり「tesseractmain.cpp」の中にある全てのソースを削除し、書き換えるのですか?
無題
現在そのお試しプログラムはお手元にあったら頂いてもよろしいのでしょうか?
無題
また、上記のソースを単純にC++ファイルを制作し、ビルドしたらこのような失敗が出ています:
tesseract-3.01\test\test\test.cpp(2): fatal error C1083: include ファイルを開けません。'baseapi.h': No such file or directory ここで、この"baseapi.h"ファイルが無いということがわかりました。やはり最初の親フォルダはtesseract-3.01フォルダではなく、Apiフォルダに指定するのですか?
無題
Apiフォルダに指定して、ビルドしたらまたこんなエラーが出ました:
tesseract-3.01\api\apitypes.h(23): fatal error C1083: include ファイルを開けません。'publictypes.h': No such file or directory いろいろ探しましたが、Publictypes.hファイルを見つかりませんので、どうすればいいんですか? Re:無題
すでにライブラリファイル(libtesseract.lib)が vs2010\Release フォルダにできているでしょうか?
できているならば、Tesseractのプロジェクトは閉じてしまって構いません。 このブログ記事のサンプルプログラムは、VC++のコマンドプロンプトコンパイラを使ってビルドしています。 もしもVC++のIDEを使いたいのであれば、以下の手順を実施してください 1.新しいプロジェクト(Win32コンソールアプリケーション)を作成する 2.対象の構成を「Release」に変更する 3.プロジェクトのプロパティを開き、 構成プロパティ → C/C++ → 全般 → 追加のインクルードディレクトリ に以下のフォルダをすべて追加します。 D:\dev\tesseract-3.01\api D:\dev\tesseract-3.01\ccstruct D:\dev\tesseract-3.01\ccutil D:\dev\tesseract-3.01\ccmain もしTesseractを別のフォルダに格納している場合は、それに合わせてパスを変更してください 4.同様に、プロジェクトのプロパティで 構成プロパティ → C/C++ → プリプロセッサ → プリプロセッサの定義 に、「__MSW32__」を追加します。 5.プロジェクトのプロパティで リンカー → 全般 → 追加のライブラリディレクトリ に以下のフォルダを追加します。 D:\dev\tesseract-3.01\vs2010\Release D:\dev\tesseract-3.01\vs2008\lib もしTesseractを別のフォルダに格納している場合は、それに合わせてパスを変更してください 6.プロジェクトのプロパティで リンカー → 入力 → 追加の依存ファイル に以下のファイル名を追加します。 libtesseract.lib liblept-static-mtdll.lib 7.お試しプログラムのソースコードを書いてビルドする。 (VC++のIDEはデフォルトでプリコンパイル済みヘッダーを使うので、 最初に stdafx.h をインクルードする必要があります。)
無題
ご返答ありがとうございました。早速試してみます。もしわからないことがあったらまたよろしくお願いします。
無題
質問です。
コメント欄で回答してくださっている VC++のIDEでの手順に沿ってビルドしたのですが、 host.hとserialis.hのヘッダファイルにおいてエラーが出てしまいます。 初心者の質問だと思いますが、何か方法がありましたら教えていただきたいです。。 以下がエラーの内容です。 よろしくお願いします。 構文エラー : ';' が、識別子 'inT64' の前に必要です。 構文エラー : ';' が、識別子 'reverse64' の前に必要です。 構文エラー : ';' が、識別子 'uinT64' の前に必要です。 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 識別子 "INT64" が定義されていません 識別子 "UINT64" が定義されていません Re:無題
プリプロセッサの定義に「__MSW32__」を追加する手順が抜けているものと思われます。
確認してみてください。
無題
素早いお返事ありがとうございます!
とても助かります。 _MSW32_ のアンダーバーは全角のアンダーバーでしょうか?? 半角のアンダーバーを用いた定義は出来ています。 もし半角のアンダーバーでしたら、他にエラーの原因はありますでしょうか(>_<) Re:無題
コピー&ペーストしてみると分かると思いますが、半角のアンダースコア「_」が2個連続で書かれています。
「_」+「_」+「MSW32」+「_」+「_」 という感じです。
無題
無事エラー解消できました。
本当にありがとうございます! また違う質問です。何度も申し訳ありません。。 日本語でのOCRをする為にバージョン3.02で動かそうと思ったのですが(バージョン3.01には日本語用がない為)、バージョン3.02にはvs2010用のプロジェクトファイルがなく、vs2008のフォルダにあるlibtesseractをビルドしても、ライブラリファイルが見つけられない状態です。 vs2010上で日本語のOCRを動かすにはどういう手順をふめばよいでしょうか。 バージョン3.02のソースファイルとtesseract用の言語データのダウンロードは出来ています。 よろしくお願いします。 Re:無題
現在の最新リリース(3.02.02)については試していないのでちょっとわからないです。
ただし、3.01でも3.00以上向けの日本語データが使用可能です。 http://code.google.com/p/tesseract-ocr/downloads/detail?name=jpn.traineddata.gz 以前にちょっと試した限りでは、出力がUTF-8で取得されるので、自分でUTF-16なりShift-JISなりに変換する必要があったと記憶しています。
無題
お礼が遅れてしまい申し訳ありませんでした。
質問にひとつひとつ丁寧に答えてくださり、本当にありがとうございました。
数字に限定したい場合
とても参考になる記事、ありがとうございます。
大変助かっております。 ひとつ質問がございます。 サンプルコードをそのまま実装させておりますが、このサンプルに追加でsetvariableにて数字のみに限定させたいと試みております。 int main(int argc, char* argv[]) { tesseract::TessBaseAPI tessBaseApi; tessBaseApi.SetVariable("tessedit_char_whitelist", "0123456789"); // If digit only tessBaseApi.Init( argv[0], // データパス (tessdata の親ディレクトリ名) "eng"); // 言語 "eng", "jpn" など STRING output; bool success = tessBaseApi.ProcessPages( "input.jpg", // 入力ファイル名 NULL, // リトライconfigファイル名 0, // タイムアウト値(msec) (0 は指定なし) &output); // 出力文字列 if (!success) { std::cout << "Error occurred.\n"; } else { std::cout << output.string(); } return success ? 0 : 1; } 上記のように tessBaseApi.SetVariable("tessedit_char_whitelist", "0123456789"); を追加しただけでは数字限定になりませんでした。 可能であればご教授いただけると幸いです。 また以下のサイトに http://www.pixel-technology.com/freeware/tessnet2/ 以下のようなサンプルコードがありました。 Bitmap image = new Bitmap("eurotext.tif"); tessnet2.Tesseract ocr = new tessnet2.Tesseract(); ocr.SetVariable("tessedit_char_whitelist", "0123456789"); // If digit only ocr.Init(@"c:\temp", "fra", false); // To use correct tessdata List<tessnet2.Word> result = ocr.DoOCR(image, Rectangle.Empty); foreach (tessnet2.Word word in result) Console.WriteLine("{0} : {1}", word.Confidence, word.Text); 上記サンプルにある tessnet2でないと実現できないのでしょうか。 このような場で大変心苦しいのですが、 よろしくお願いいたします。 Re:数字に限定したい場合
SetVariable() は Init() の後で呼び出す必要があるようです。
|
プロフィール
HN:
はむぱい
職業:
ソフト作ったりしてる人
Twitter
カテゴリー
最新CM
[06/09 replica rolex oyster perpetual datejust]
[06/09 bracelets imitation cartier love]
[06/09 replica the oyster perpetual datejust]
[06/09 datejust rolex oyster perpetual]
[06/09 replica gold love bangle]
カレンダー
ブログ内検索
あ~いい漢字
|