この記事は、OpenSiv3D Challenge 2021 Challenge 09 | 手書き数字・英字の認識の一環として書いたものです。OpenSiv3Dで文字認識を行うために必要な手順をまとめました。
準備
使用するもの
- OpenSiv3D v0.6
- OpenCV(4.5.1)
- OpenCV_contrib(4.5.1)
- Tesseract(4.1)
この記事ではWindows10(64bit)でVisual Studio 2019, Cmakeを使うものとします。また、事前にVisual Studioインストーラーから英語の言語パックを追加しておく必要があります。
OpenSiv3Dのインストール
現在、OepnSiv3D v0.6を使うには自分でビルドする必要があります。まずOpenSiv3Dのソースコードをダウンロードします。
詳しい手順はOpenSiv3D | ライブラリの自前ビルドを参考にしてください。
Tesseractのインストール
- Visual StudioインストーラーからVisual Studioに英語の言語パックを追加します。(追加していない場合)
- Tesseractはvcpkgからインストールすることができます。まずvcpkgをGitHubからダウンロードし、中にある「bootstrap-vcpkg.bat」を実行します。
- vcpkgのある場所で管理者権限でコマンドプロンプトを開き
vcpkg install tesseract:x64-windows
というコマンドを実行します。 - しばらく待つとインストールが完了します。
OpenCV, OpenCV_contribのインストール
-
GitHubからOpenCVとOpenCV_contribのソースコードをダウンロードします。
-
Cmake-GUIを開きます。「Where is the source code:」のところにOpenCVのsourceを指定します。「Where to build the binaries」にはビルドしたファイルを置く場所を指定します。この場所は後で使うので、できるだけ分かりやすい場所がお勧めです。今回は
opencv_build
というフォルダを新しく作りそこに保存することにしました。 -
「Configure」をクリックし、出てくるウィンドウでは「Visual Studio 16 2019 Win64」を選択して「finish」をクリックします。
-
Name「OPENCV_EXTRA_MODULES_PATH」のValueに「opencv_contrib」を展開した先の「/modules」を設定します。もう一度「Configure」をクリックします。
-
Name「Tesseract_DIR」には「C:/.../vcpkg-master/x64-windows/share/tesseract」を、「Leptonica_DIR」には「C:/.../vcpkg-master/x64-windows/share/tesseract」を指定します。その他のオプションは自由です。ただし、**「BUILD_opencv_world」は必ずOFFにしてください。**これをOFFにしないと後で必要になるファイルが生成されなくなります。
-
もう一度「Configure」をクリックし、次に「Generate」をクリック。さらに、「Open Project」をクリックしてVisual Studio 2019を開きます。
-
ビルドからバッチビルドを選択し、ALL_BUILDとINSTALLのDebug, Releaseの両方にチェックを入れ、ビルドをクリックします。
-
ビルドはPCのスペックによりますが1時間ほどかかります。これでOpenCVの準備は完了です。1
Visual Studioの設定
OpenSiv3DのソースコードをVisual Studioで開くとSiv3D-Test
というプロジェクトが同梱されており、それを使うことでOpenSiv3Dのサンプルを動かすことができるようになっています。今回はそのプロジェクトのプロパティを書き換えることでOpenCVを利用できるようにしていきます。
1.まず、プロジェクトからプロパティを開き、VC++ディレクトリのインクルードディレクトリに
C:\ ...\opencv_build\install\include
を追加します。また、ライブラリディレクトリに
C:\ ...\opencv_build\install\x64\vc16\lib
C:\ ...\vcpkg-master\installed\x64-windows\lib
C:\ ...\vcpkg-master\installed\x64-windows\debug\lib
の3つを追加します。
- プロパティのリンカーから入力を選び、その中の追加の依存ファイルに
C:\ ...\opencv_build\install\x64\vc16\lib\opencv_text451d.lib
C:\ ...\opencv_build\install\x64\vc16\lib\opencv_dnn451d.lib
C:\ ...\opencv_build\install\x64\vc16\lib\opencv_highgui451d.lib
C:\ ...\opencv_build\install\x64\vc16\lib\opencv_features2d451d.lib
C:\ ...\vcpkg-master\installed\x64-windows\debug\lib\tesseract41d.lib
の5つを追加します。 - C:...\vcpkg-master\installed\x64-windows\debug\binにある全てのファイルを、実行ファイルがあるフォルダ(ここからは
App
フォルダにあるものとします)にコピーします。 -
https://github.com/tesseract-ocr/tessdata_fast からjpn.traineddata(縦書きの文章を認識したい場合はjpn_vert.traineddata)をダウンロードします。ダウンロードしたファイルは、
App
フォルダに新しくフォルダを作り、その中に置いてください。(ここではdata
というフォルダを作ったものとします。)2 - 認識させたい画像を用意します3。読み込みたい画像ファイルのパスは、 App フォルダを基準とする相対パスか、絶対パスを使用してください。
- Main.cppに文字認識を行うためのコードを書きます。ここではopencvで文字認識その1 Tesseractラッパ を参考にしました。
# include <Siv3D.hpp> // OpenSiv3D v0.6
# include <Siv3D/OpenCV_Bridge.hpp>
# include <opencv2/opencv.hpp>
# include <opencv2/text.hpp>
SIV3D_SET(EngineOption::Renderer::Direct3D11)
//SIV3D_SET(EngineOption::Renderer::OpenGL)
//SIV3D_SET(EngineOption::D3D11Driver::WARP)
void Main()
{
// Scene::SetBackground(ColorF{ 0.8, 0.9, 1.0 });
Scene::SetBackground(Palette::Black);
Scene::SetResizeMode(ResizeMode::Keep);
Window::SetStyle(WindowStyle::Sizable);
// Window::Resize(1280, 720);
// 画像読み込み
cv::Mat image = cv::imread("example\\hayakuchi.png");
Print << image.size().width;
// グレースケール化
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_RGB2GRAY);
// 文字認識クラスのインスタンス生成
auto ocr = cv::text::OCRTesseract::create("data\\", "jpn");
// ホワイトリストを消す
// これを書かないとアルファベットと数字しか認識しない
ocr->setWhiteList("");
std::string text;
std::vector<cv::Rect> boxes;
std::vector<std::string> words;
std::vector<float> confidences;
// 文字認識の実行
ocr->run(gray, text, &boxes, &words, &confidences);
// 結果出力
String s;
if (boxes.size() > 0) {
// 文字コードを変換
s = Unicode::FromUTF8(text);
}
Print << s;
while (System::Update())
{
}
}
6. Ctrl + F5を押して実行してください。
7. ビルドエラーが発生した場合は、インクルードディレクトリやライブラリディレクトリが正しく設定されているか確認してください。ビルドが成功して実行する段階でエラーが発生した場合は、画像やtraineddataファイル、dllファイルがAppフォルダにあるかを確認してみてください。
実行結果
今回、認識に使った画像と認識結果は以下の通りです。
認識結果 | 元の画像 |
手書き文字での認識結果は以下の通りです。 |
認識結果 | 元の画像 |
デジタルな文字については十分な精度で認識ができますが、手書き文字についてはまだ工夫が必要なようです。
参考資料
https://qiita.com/lilac0011/items/9fe6e061c3a036689a36
http://whoopsidaisies.hatenablog.com/entry/2014/11/12/003100
https://zenn.dev/reputeless/articles/article-build-siv3d
https://siv3d.github.io/ja-jp/tutorial/texture/#56