OpenCVを使って動体検出(face-detectionとか)を行う場合に使用するCascadeClassifier.detectMultiScaleについて、パラメータを変えて試してみる。
前回に引き続き今回は、minNeighborsを変えて試してみました。
Method Detail
public void detectMultiScale(Mat image, MatOfRect objects, double scaleFactor, int minNeighbors, int flag, Size minSize, Size maxSize)
- image:
- objects:
- scaleFactor:
- minNeighbors:
- flags:
- minSize:
- maxSize:
CV_8U型の行列。ここに格納されていいる画像中から物体が検出されます。
矩形を要素とするベクトル。それぞれの矩形には、検出した物体を含みます。
画像スケールにおける縮小量を表します。
物体候補となる矩形は、最低でもこの数だけの近傍矩形を含む必要があります。
このパラメータは、新しいカスケードでは使用されません。古いカスケードに対しては、cvHaarDetectObjects関数の場合と同じ意味を持ちます。
物体が取り得る最小サイズ。これよりも小さい物体は無視されます。
物体が取り得る最大サイズ。
minNeighborsは信頼性のパラメータで、値が大きくなるに連れて検出の信頼性が上がるようですが、見逃してしまう率も高くなるようです。
detectMultiScaleでは画像のスケールを変えて何度も探索を行います。その結果、分類器がTrueとなる箇所が何度も重複して検出されますが、より重複(近傍矩形を含む)が多い部分を信頼性が高いと考えます。そのしきい値がminNeighborsになります。
(詳しくは、結果の画像を見ていただけるとよくわかると思います)
今回やったこと
minNeibhorsを変化させて、
・検出精度(誤検出数、見送り率)
・処理時間
を調べる。
実験に使用した画像はフリー素材で見つけてきたサイズの異なる画像5枚(顔55個を含む)を使用。
環境
・Ubuntu 14.04 64bit (CPU:Intel Core i5 660@3.33GHzx4, MEM:3.9GB)
・OpenCV 2.4.10
・Java 1.8.0_40
実験プログラムはJavaで記述しています。
カスケード型分類器にはhaarcascade_frontalface_default.xmlを使用しています。
scaleFactor以外のパラメータは、scaleFactor=1.1, flags=CASCADE_SCALE_IMAGE, minSize=30×30, maxSize=なしです。
結果
minNeighbors別の誤検出数
minNeighbors別の見逃し率
今回の実験結果からだと、minNeighborsは2,3あたりがパフォーマンスが良かった。
実際の検出結果を見てみると、minNeighborsがどう作用しているかがよくわかる。
minNeihbors=0の場合は、近傍矩形がない=検出したすべての矩形が得られる。
minNeihbors=1の場合は、近傍矩形が最低1個なので、上記の画像の例では、右上と左下が削除された結果となる。
minNeihbors=2の場合は、近傍矩形が最低2個なので、右下も削除される。
minNeighborsの設定はいくつにしておけば良いという訳ではなく、分類器の精度やscaleFactorによって最適な値を見つけてあげる必要がありそう。
処理負荷を減らすためにscaleFactorを大きくした場合は、minNeihborsを下げてあげないと検出できなくなるなど。
バランスを見ながら設定するパラメータだと思われる。
処理時間
minNeighborsによる違いは特にないようです。
今回調べたのは以上になります。
あとがき
scaleFactorとminNeighborsを調べて、なんとなくですがdetectMultiScaleの使い方が分かってきた気がする。