OpenCVのサンプルコードでEnetを動かしてみた
はじめに
OpenCVのサンプルコードを使って、Enet(Semantic Segmentationのモデル)を試してみました
Enetとは
[1]で提案されている、Semantic Segmentationのネットワークです
リアルタイム向けに設計されており、SegNet等の従来のネットワークよりも演算量やパラメータ数が少なく、高速なのが特徴です
既に色々なフレームワークで実装されていますが、OpenCVではバージョン3.3から、dnnモジュールが追加されたのに伴い、
Enetの学習済みモデルとサンプルコードが提供されたようです
[1] ENet: A Deep Neural Network Architecture for Real-Time Semantic Segmentation
ビルド
BUILD_EXAMPLES=ON
を指定してOpenCVをビルドすれば使用することができます
opencv/samples/dnnからsegmentation.cppとcommon.hppをもってきて自前でビルドするも良し
学習済みモデルのダウンロード
opencv_extra/testdata/dnn/download_models.pyを叩くとダウンロードできます
ただしそのまま叩くとdnnサンプルに含まれるすべてのモデルがダウンロードされるので、Enetだけ欲しい場合はスクリプトを修正すると良いでしょう
ちなみに、Cityscapes Dataset+Torchで学習したもののようです
実行
実行コマンドの例を示します
./example_dnn_segmentation enet --input=input.avi --zoo=models.yml --model=Enet-model-best.net --classes=enet-classes.txt --colors=colors.txt --target=1
以下、オプションと設定時の動作について解説します
enet
- モデル名を指定します
- モデル名に対応する設定をmodels.ymlから読み取ります
input=input.avi
- 入力ファイルを指定します
cv::VideoCapture
を使用しており、--input=image_%03d.png
のように連番画像の指定も可能です(cv::VideoCapture
が連番対応してることを書いてて知った!)
--zoo=models.yml
- models.ymlのパスを指定します
- サンプルコードと同じopencv/samples/dnnにあります
- 指定しない場合はカレントディレクトリのmodels.ymlを探します
--model=Enet-model-best.net
- 学習済みモデルのパスを指定します
- 指定しない場合は以下の環境変数からEnet-model-best.netを探します
OPENCV_DNN_TEST_DATA_PATH
OPENCV_TEST_DATA_PATH
--classes=enet-classes.txt
- 分類クラスの定義ファイルを指定します
- opencv/samples/data/dnn/enet-classes.txtから入手可能です
- 指定しなくても動きますが、指定すると以下のようにクラス名と色付けの対応を表示してくれます
--colors=colors.txt
- 各クラスの色付けを指定します
- 指定しない場合はランダムで色付けされます
- TimoSaemann/ENetのものと同じ色設定を作成したのでよかったらお使い下さい
0 0 0 128 64 128 244 35 232 70 70 70 102 102 156 190 153 153 153 153 153 250 170 30 220 220 0 107 142 35 152 251 152 70 130 180 220 20 60 255 0 0 0 0 142 0 0 70 0 60 100 0 80 100 0 0 230 119 11 32
--target=1
結果
KITTIデータセットで実行した結果を動画にしました
上半分がネットワークへの入力解像度512x256
の結果、下半分が1024x256
の結果です
1024x256
の方が若干精度が良いように見えます
処理時間は入力解像度512x256
の場合、--target=0(CPU)
で約80[msec]、--target=1(OpenCL)
で約20[msec]でした…速い!
1024x256
にするとOpenCLで2倍の約40[msec]かかりましたが、それでも十分速い印象です
おわりに
OpenCVでEnetを動かしてみました
趣味で作りたいプログラムにSemantic Segmentation(特に車載向け)を使うものがあり、以前からEnetには注目してたのですが、慣れ親しんだOpenCVで使えるようになって感激です!