しょうがないので、偉大な誰かが作った文字認識エンジンをありがたく使わせていただく事に。
そんなこんなで本日作ったガラクタは、以下のようなカメラ映像から、赤枠内の文字を認識してくれるというシロモノだよ。


これを作るためにいろいろ探していたら、Tesseract-OCR という文字認識エンジンを見つけたので、さっそくダウンロード。 Windows 環境なら、tesseract-ocr-setup-3.00.exe あたりを落とせば幸せになれると思う。
これを、C:\Program Files\Tesseract-OCR というフォルダにインストール。
使い方は、認識させたい画像を tiff 形式(たとえば tmp.tiff )で保存して、コマンドラインに
tesseract.exe tmp.tiff resultと打ち込む。
すると、自動的に生成されたテキストファイル(result.txt)に結果が書き込まれるのだ。
つまり、ぼくが実装するのは検出対象領域の tiff 画像を作り、tesseract.exe を呼ぶ事くらい。ほとんどオートマチックに実現できてしまう。
- #include<cv.h>
- #include<cxcore.h>
- #include<highgui.h>
- #include<fstream>
- #include<iostream>
- #include<string>
- #include<cstdlib>
- #pragma comment(lib,"cv200.lib")
- #pragma comment(lib,"cxcore200.lib")
- #pragma comment(lib,"highgui200.lib")
- int main() {
- CvCapture* capture = NULL;
- if((capture = cvCreateCameraCapture(0)) == NULL)
- return -1;
- cvNamedWindow("カメラ映像", CV_WINDOW_AUTOSIZE);
- IplImage* rgbImg;
- while(1) {
- // ====================
- // カメラからキャプチャ
- // ====================
- rgbImg = cvQueryFrame(capture);
- // 識別対象枠の表示
- int fieldSize = (int)(rgbImg->height * 0.9);
- cvRectangle(rgbImg,
- cvPoint(
- (rgbImg->width - fieldSize) / 2 -1,
- (rgbImg->height - fieldSize) / 2 -1),
- cvPoint(
- (rgbImg->width + fieldSize) / 2 +1,
- (rgbImg->height + fieldSize) / 2 +1),
- cvScalar(0, 0, 255));
- cvShowImage("カメラ映像", rgbImg);
- // =======
- // ROI設定
- // =======
- cvSetImageROI(rgbImg,
- cvRect((rgbImg->width - fieldSize) / 2,
- (rgbImg->height - fieldSize) / 2,
- fieldSize, fieldSize));
- int key = cvWaitKey(33);
- // ===========================
- // Sキーが押されたら、文字認識
- // ===========================
- if (key == 's') {
- cvSaveImage("test.tiff", rgbImg);
- // コマンド実行(結果はtmp.txtに保存)
- system("\"C:\\Program Files\\Tesseract-OCR\\tesseract.exe\" test.tiff tmp");
- system("cls");
- // tmp.txtの内容を表示
- std::ifstream ifs("tmp.txt");
- std::string str;
- ifs >> str;
- std::cout << "「" << str <<
- "」…と、検出されました。" << std::endl;
- }
- cvResetImageROI(rgbImg);
- if (key == 'q') break;
- }
- cvReleaseCapture(&capture);
- cvReleaseImage(&rgbImg);
- cvDestroyWindow("カメラ映像");
- return 0;
- }
操作方法は、対象物を写しつつ s キーを押すだけ。
すると、赤枠内の対象領域が test.tiff として保存され、tesseract.exe が呼ばれる。
![]() |
保存された「test.tiff」 |
検出した文字は std::string オブジェクトに格納されるので、煮るなり焼くなりし放題だ(今回は単に表示しただけ)。
前回よりだいぶマシになったものの、残念ながら精度はまだ満足いくものではない(誤検出がけっこう多い)。
さらに前処理などを加える事で改善できそうな気もするけれど、ちょっと骨が折れそうなのでまた今度。
こういう組合せ方ができるんですね!大変参考になりました
返信削除コメントありがとうございます。非常に励みになります。
返信削除CUI アプリケーションならではの“部品としてプログラムに組み込みやすい”という利点に、興味を抱いて頂けたら幸いです。
Tesseractをダウンロードしてインストールしましたが、どの.exeファイルを実行してもコマンド窓が出ないのです。どうすればいいんですか?
返信削除大変参考にさせていただいております。ありがとうございます。
返信削除日本語でOCRをする場合、どのように記述すれば実行できるでしょうか。
日本語の言語ファイルはインストールしています。
御手数ですが、よろしくお願いします。