「目」を検出してみる

OpenCVには、物体検出の機械学習をするツールが付いてきます。これを使うと、顔以外の検出器を作ることができます。コードを読むのをちょっとお休みして、これを試してみました×
参考ページ: http://ugd555.blog1.fc2.com/blog-category-30.html
今回は「目」の検出に挑戦してみました。ポジティブイメージ(正解例)として、以下の9個を用意しました×

ネガティブイメージ(正解を含まない例)は以下の9個です×

「マトモな検出器を作るにはポジティブ7000例、ネガティブ3000例は必要」らしいので、全然足りてないんですが… まあ、とりあえずやってみましょう×

1個も検出できていません。うーん。さすがに無理がありますかね。ただ、顔の部分がちょっと小さすぎるかもしれません。もうちょっと大きな画像で試してみましょう×

おお!1箇所誤検出がありますが、なかなかの成績です。調子に乗って他のもいってみましょう×

おおお!さすが世界のダンコーガイさんですね!赤い眼鏡もステキです×
……と、随分とうまくいったように見えますが、実はちょっとズルをしています。OpenCVの物体検出器は、最終的な結果を出す一歩手前で、以下のような状態になっています×

水色の四角は、「ここが顔かもしれない」という候補です。又吉さんの顔の部分に大量に四角が重なっていますね。このように、同じ場所に候補が重なっているところを最終的な結果として残して、重複が少ないところを消してしまいます。その結果、以下のようなきれいな結果が出るわけですね×

ここでの「何個以上重複した部分を残すか」という閾値は、自由に変えることができます。閾値を下げれば「甘く」なるわけですね。水樹奈々ちゃんのときは4、ダンコーガイさんのときは2、と人為的に操作して、結果を良くしていたわけです(論文を書いたりするときにこんなことをしてはいけませんよ)。ちなみに、水樹奈々ちゃんの画像で閾値を2にすると、こんな感じになります×

眉毛まで検出しちゃってます。まあ、学習用の画像がたった9個ならこの程度でしょう×
余談ですが、3つ上の画像(重複を処理する前の結果)の画像も、JSONでダンプしてCanvasのstrokeRectで描画、という手順で作りました。便利ですね、Canvas×