読者です 読者をやめる 読者になる 読者になる

opencvで文字認識その1 Tesseractラッパ

C++ OpenCV OpenCV 3.0 Programming コンピュータビジョン

OpenCV3.0系から文字認識モジュールが搭載されるようなので使ってみる.現状の3.0 alphaや3.0 betaでは,文字認識モジュールはメインレポジトリに組み込まれておらず開発用レポジトリのopencv_contribの方に入っているようで,opencv_contribと一緒にOpenCVをビルドする必要がある.

OpenCVの文字認識モジュール

OpenCVのドキュメントによると,以下の2種類の文字認識方法があるらしい.

  1. オープンソースのOCRライブラリtesseract-ocrを呼び出す方法
  2. 隠れマルコフモデルによる認識方法

今回は,1の方法について試してみる.

文字認識モジュールの準備

tesseract-ocrのダウンロード

https://code.google.com/p/tesseract-ocr/downloads/listからVC++からtesseract-ocrを呼び出す用のライブラリをダウンロード・解凍する.「tesseract-3.xx.xx-win32-lib-include-dirs.zip」って名前のやつ.今回は「tesseract-3.02.02-win32-lib-include-dirs.zip」を使った.

https://code.google.com/p/tesseract-ocr/downloads/listからtesseract-ocr用の学習済みのデータファイルをダウンロードしておく.今回は英語で試すため「tesseract-ocr-3.02.eng.tar.gz」をダウンロード・解凍する.

opencv_contribのダウンロード

https://github.com/itseez/opencv_contribからopencv_contribをダウンロード・解凍する.

OpenCVのビルド

CMakeを使ってビルドする.ここらへんを参考に.

「OPENCV_EXTRA_MODULES_PATH」パラメータの値を「(opencv_contribのパス)/modules」にセットしてConfigureする.

すると「Tesseract_INCLUDE_DIR」と「Tesseract_LIBRARY」というパラメータが出てくるので

  • Tesseract_INCLUDE_DIR ← (tesseract-ocrのパス)/include
  • Tesseract_LIBRARY ← (tesseract-ocrのパス)/lib

とセットする.

以上の設定でGenerateしてOpenCVをビルドすると文字認識モジュールが組み込まれる.で,インストールする.

動作確認

実際に画像を入力してやってみたソースコードと結果が以下.OpenCVのMat形式の画像を使って文字認識出来るため,tesseract-ocrのAPI直接叩くよりは使いやすいと思う.

追記)文字のかたまりの位置の出力が間違っていたためソースコードと結果画像を修正した.

ソースコード
#include <opencv2/opencv.hpp>
#include <opencv2/text.hpp>

void main()
{
	// 画像読み込み
	auto image = cv::imread("moji.jpg");
	// グレースケール化
	cv::Mat gray;
	cv::cvtColor(image, gray, COLOR_RGB2GRAY);
	// 文字認識クラスのインスタンス生成
	auto ocr = cv::text::OCRTesseract::create("(言語データのパス)/tessdata", "eng");

	std::string text;
	std::vector<cv::Rect> boxes;
	std::vector<std::string> words;
	vector<float> confidences;
	// 文字認識の実行
	ocr->run(gray, text, &boxes, &words, &confidences);

	// 結果出力
	printf("%s\n", text.c_str());
	// 文字のかたまりごとに出力
	printf(" 文字      | 位置       | 大きさ     | 信頼度\n");
	printf("-----------+------------+------------+----------\n");
	for (int i = 0; i < boxes.size(); i++)
	{
		printf("%-10s | (%3d, %3d) | (%3d, %3d) | %f\n",
			words[i].c_str(),
			boxes[i].x, boxes[i].y,
			boxes[i].width, boxes[i].height,
			confidences[i]);
	}
}
実行結果

f:id:whoopsidaisies:20141112103657p:plain