今回は、OpenCV 3.4.3以降で導入されたMask R-CNNを使って、OpenCV&Mask R-CNNでオブジェクトの認識&セグメンテーションを行ってみようという内容です。
Mask R-CNNはCNN(畳み込みニューラルネットワーク)を使って、セグメンテーションができる技術でFacebookのAI Researchより論文が出ています。Mask R-CNNで検索すれば論文が出てくると思うので、アルゴリズムの詳細を知りたい方はそちらを参照してください。
ベースはFaster R-CNNに、Mask抽出のブランチを付け加えることでマスク抽出を可能とするものですが、以下のようにMaskの抽出ができます(Laptopが二重に認識されてますが)。
目次
今回の環境
・OS : Windows10(64bit)
・Visual Studio 2015 Community(インストール済)
・OpenCV 4.0.0
OpenCV4.0.0の環境構築を行い、その後にMask R-CNNの認識結果を確認していきます。
手順
(1) OpenCV 4.0.0のインストール
以下のOpenCVの公式よりOpenCV4.0.0のWin packをダウンロードします。
外部サイト:OpenCV(Release)
ダウンロードが完了すると、以下のようなインストーラーが得られるので、任意のフォルダで実行します。
OpenCV4.0.0のファイルをどこに展開するか指示されますが、自分が扱いやすい任意のフォルダに展開します。
展開したフォルダにOpenCVフォルダができていれば成功です。この中にビルド済のOpenCVのヘッダやライブラリが展開されています。
一応バージョンがわかるように「opencv」フォルダを「opencv_4_0_0」にリネームしておきました。これでOpenCV 4.0.0のインストールは完了です。
(2) Mask R-CNNのソースコードとビルド
それでは、Mask R-CNNのソースコードをVisual Studioでビルドしていきましょう。
英語ですが、以下のサイトを参考にさせていただきました。
参考サイト:Learn OpenCV
まず、Visual Studioのプロジェクトを作成し、以下の「main.cpp」「mask_r_cnn.h」「mask_r_cnn.cpp」のソースコードを準備します。
x64/Releaseとし、OpenCVのパスを設定していきます。
(1)でインストールしたOpenCVのパスを通していきます。
インクルードディレクトリを「\build\include」のフォルダに設定、
追加のライブラリディレクトリを「\build\x64\vc14\lib」に設定し、
追加の依存ファイルに「opencv_world400.lib」を加えます。
これで設定を適用させ、プロパティぺージを閉じて、一度ビルドしてみてください。
正しくパスが設定されていればビルドが通るはずです。
これでビルドは通るはずですが、このままだと「opencv_world400.dll」がないと怒られるはずなので、「\build\x64\vc14\bin」のフォルダから「opencv_world400.dll」をコピーし、当該プロジェクトの中の「x64\Release」のフォルダの中にコピーしてください。
これでVisual Studioのプロジェクトは完成ですが、プログラムからMask R-CNNのモデルやパラメータファイルなどをロードする必要があり、ロードするための各種ファイルを入手してくる必要があります。
入手するファイルは、main.cppの7~10行目で設定したパスに置く必要があります。
String text_graph = "..\\..\\model\\mask_rcnn_inception_v2_coco_2018_01_28.pbtxt"; String model_weights = "..\\..\\model\\mask_rcnn_inception_v2_coco_2018_01_28\\frozen_inference_graph.pb"; String classes_file = "..\\..\\model\\mscoco_labels.txt"; String colors_file = "..\\..\\model\\colors.txt";
四つのファイルを入手する必要があります。
(3) Mask R-CNNのモデルやパラメータファイルの入手
Mask R-CNNをOpenCVで動かすために、
① モデルのアーキテクチャを示すファイル
② 訓練済の重みファイル
③ ラベル名等を設定するファイル
を手に入れましょう。
①はOpenCV extraの中に入っており、以下のgithubからダウンロードしました。「mask_rcnn_inception_v2_coco_2018_01_28.pbtxt」というファイルです。
外部サイト:Github(opencv_extra)
②はtensorflow.orgからダウンロードでき、以下のリンクよりダウンロードしたファイルを解凍してください。
外部サイト:Tensorflow(mask_r_cnn)
③として、最後に認識後のラベル名や色を設定するファイルを用意します。
の2点をダウンロードしてください。
今回は集めたファイルをmodelフォルダとして一つにまとめました。
main.cppの7~10行目に、各ファイルへのパスを設定してください。正常にパスが設定されていれば、これでプログラムが動くはずです。
二つ目のmodel_weightsは「mask_rcnn_inception_v2_coco_2018_01_28」フォルダ内の「frozen_inference_graph.pb」にパスを通します。
String text_graph = "..\\..\\model\\mask_rcnn_inception_v2_coco_2018_01_28.pbtxt"; String model_weights = "..\\..\\model\\mask_rcnn_inception_v2_coco_2018_01_28\\frozen_inference_graph.pb"; String classes_file = "..\\..\\model\\mscoco_labels.txt"; String colors_file = "..\\..\\model\\colors.txt";
ここまで設定ができたら、認識させたい画像と、出力画像のファイル名(任意)をmain.cppの13行目に入れてください。
mask_r_cnn_detector_.imageExec("test.jpg", "output.jpg");
(4) 実行結果
以下のような画像を入力したところ、
以下のような出力を得ました。しっかりとマスクの抽出もできているようですが、Laptopが二つ認識されているミスがあります。ただ、概ね結果は正しいと言えるでしょう。
まとめ
OpenCV4.0.0を使ったMask R-CNNの実行をやってみました。
簡単なコードで、C++の他のプログラムにMask R-CNNの機能を加えたりすることができそうです。
もし、まず簡単にMask R-CNNを試したいということであれば、OpenCVを使ってみるのも悪くなさそうです。
詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識