見出し画像

[Python]カスケード分類器で動画上から特定の画像を検出する[OpenCV]②

前回の続きになります。今回はコマンドプロンプトを使って、カスケード分類器を作成します。

フォルダ構成

任意のフォルダを作成し、その中に以下のようなフォルダ(pos,neg,vec,cascade)を作成しました。
pos→ポジティブ画像フォルダ(判断したい画像)
--poslist.txt
neg→ネガティブ画像フォルダ(判断したいものが映っていない画像)
--nglist.txt
vec→ベクトルファイルを入れるフォルダ
cascade→--カスケード分類器を作成するフォルダ

おなじフォルダ内に前回ダウンロードした

  • opencv_traincascade.exe

  • opencv_world346.dll

  • opencv_createsamples.exe

も配置しておきます。

画像を集める

ポジティブ画像(判断したい画像)を7枚程度集め、posフォルダへ格納します。

検知したい特定の人。写真は複数のアングルで用意します。


同様にネガティブ画像(判断したいものが映っていない画像)も集めます。今回は犬や別人の画像を150枚ほど集めました。

検出対象が映っていない画像を用意

ポジティブリスト(poslist.txt)の作成

テキストファイルで画像のリストを作成します。
リストの作成方法は下記の参考サイトを参照しました。
座標には検出したい物体の座標を入力します。

poslist.txt

#posフォルダに作成
#ファイル名 個数 物体座標の順番
#枚数分を作成
pos\picture1.jpg 1 0 0 200 300

ネガティブリスト(nglist.txt)の作成

不正解画像は座標の指定などは必要ありません。ただ、やはりリスト化する必要があります。

# 枚数分を作成
.\neg\xxx.jpg

なお、画像リストの作成をすべて手入力でやろうとするとかなりの苦痛となります…。
negフォルダまで移動し、下記のようなコマンドをコマンドプロンプトから入力することで一瞬で作成できます。

#nglistの作成
'dir *.jpg /b > nglist.txt'

モデル構築(ベクトルファイルの作成)

正解画像の準備ができましたらベクトルファイルを作成します。前回、opencv_createsamples.exeを格納したフォルダまで移動します。

詳しい手順は以下のサイト「訓練ファイルの準備」を参考にしています。

上記のサイトにあるように、ベクトルファイルの結合には「mergevec.py」が必要です。githubよりダウンロードができます。

#複数のベクトルファイルを作成します。
opencv_createsamples -img pos/picture001.png -vec vec/Va001.vec -num 1000 -w 160 -h 120
opencv_createsamples -img pos/picture002.png -vec vec/Va002.vec -num 1000 -w 160 -h 120
opencv_createsamples -img pos/picture003.png -vec vec/Va003.vec -num 1000 -w 160 -h 120
opencv_createsamples -img pos/picture004.png -vec vec/Va004.vec -num 1000 -w 160 -h 120
opencv_createsamples -img pos/picture005.png -vec vec/Va005.vec -num 1000 -w 160 -h 120
opencv_createsamples -img pos/picture006.png -vec vec/Va006.vec -num 1000 -w 160 -h 120
#vecフォルダの中データを結合してpos.vecという名前で保存
#anacondaプロンプトより実行。
python mergevec.py -v vec -o vec/pos.vec

これで、pos.vecというベクトルファイルが一つ作成されます。なお、ベクトルファイル作成時には画像の水増しが行われるわけですが、どのように水増しされているかが気になるところです。

opencv_createsamples -img pos/picture001.png -vec vec/Va001.vec -num 1000 -w 160 -h 120 -show

のように、-showオプションをつけることで画像の回転、反転といった変化を可視化することができます。ある程度見たらEscキーで終了します。
今回はデフォルト設定のままで画像に変化を加えていますが、水増しに必要なパラメータを変更することもできます。下記のサイトに詳しいオプションが記載されていますので、必要に応じて検討してみてください。

モデル構築(カスケード分類器の作成)

さて、ベクトルファイルまで作成ができましたらあとは分類器を作成します。こちらも、前回、opencv_traincascade.exeを作成したフォルダにてコマンドプロンプト上から実行します。

opencv_traincascade -data cascade -vec vec/pos.vec -bg neglist/nglist.txt -numPos 5500 -numNeg 120 -numStages 20 -featureType LBP -w 160 -h 120

numPosは正解画像、numNegは不正解画像の枚数をそれぞれ入力しますが、
実際の画像ファイルの8~9割程度の数にしないとエラーがでるとのこと。
それ以外の引数については参考サイトをご確認ください。

このような画面になると学習が始まります。

学習中

なお、PCのスペックにもよるかと思いますが、画像ファイルが大きくなるほど時間がかかるようです。
CPU:Intel(R) Core(TM) i7-8550U CPU @ 1.80GHzのノートPCで15時間ほどかかりましたが、GPUが利用できるともっと効率よく計算が進むと思います。

生成完了

学習が完了すると、cascadeフォルダ内に「cascade.xml」ファイルが生成されます。このファイルを用いて物体検出を行いますが、長くなったので続きは次回にします。
次回はwebカメラから画像を取り込み、リアルタイムで特定の人物を検出できるようなプログラムをPythonでまとめる予定です。

この記事が気に入ったらサポートをしてみませんか?