takminの書きっぱなし備忘録 このページをアンテナに追加 RSSフィード Twitter

2014-07-13

OpenCVのtraincascadeのnumPos引数はvecファイル内のサンプル数より少ない数を設定すること

| 01:16 | OpenCVのtraincascadeのnumPos引数はvecファイル内のサンプル数より少ない数を設定することを含むブックマーク OpenCVのtraincascadeのnumPos引数はvecファイル内のサンプル数より少ない数を設定することのブックマークコメント

OpenCVの物体検出器を学習する際の注意点。


物体検出器の原理や学習方法については、ここを読んで下さい。


で、たとえば

opencv_createsamples -info positive.txt -num 1000 -vec hoge.vec -w 30 -h 30

みたいな感じで1000枚の正例画像からvecファイルを作ったとします。


次に

opencv_traincascade -data hoge -vec hoge.vec -bg negative.txt -numPos 1000 -numNeg 3000 -numStages 5 -w 30 -h 30 -minHitRate 0.995 -maxFalseAlarmRate 0.4

という感じで学習をさせると、以下のようなエラーが出ます。

OpenCV Error: Bad argument (Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.) in get, file /home/user/opencv/apps/traincascade/imagestorage.cpp, line 159
terminate called after throwing an instance of 'cv::Exception'

この原因と対処法は、ここらへんに書いてあります。

http://answers.opencv.org/question/776/error-in-parameter-of-traincascade/?answer=792#post-id-792

http://answers.opencv.org/question/4368/traincascade-error-bad-argument-can-not-get-new/


で、要約すると対処法は以下の式にしたがってnumPos引数の値を決めればOKです。


numPos =< (N-S) / (numStage + minHitRate - minHitRate * numStage)


ここで、Nはvecファイル内のサンプル数、Sは適当なバッファです。

またnumPos、minHitRate、numStageは、それぞれopencv_traincascadeの引数

  • minHitRateは各ステージで満たすべき最小認識率
  • numPosは1つのステージで使用する正例の数
  • numStagesはステージ数

です。


以下、なぜそういうことになるのか興味のある人だけ読んで下さい。


学習の各ステージではvecファイル内のサンプルのうち、numPosだけが使用されます。

そして各ステージの最悪のケースでは、


numPos * (1-minHitRate)


の数だけの学習サンプル(正例)が背景と誤認識される可能性があります。

ここで背景と判断されたサンプルは、以後のステージでは使用されません。


したがって、棄却された分のサンプルを新たにvecファイルから継ぎ足してやる必要があります。

vecファイル内のサンプル数をNとすると、


N >= numPos + numPos * (1 - minHitRate) * (numStages - 1)


を満たす必要があります。さらに、各ステージでvecファイルから新たに追加されたサンプルが、現在のステージの識別器で(次のステージで使用される前に)即座に背景として棄却される場合もあり得るので、その数を仮にSとすると、


N >= numPos + numPos * (1 - minHitRate) * (numStages - 1) + S


となります。

したがって、numPosは以下の式にしたがって求めれば良いことになります。


numPos =< (N-S) / (numStage + minHitRate - minHitRate * numStage)

リンク元