Detection機能で、画像から顔を検出するAPIを作ってみた。Classifiers)というのを用いるやつ。CascadesOpenCVには顔や目などに関して学習済みのデータが同梱されているので、これを使うことで簡単に画像から顔を検出できる。ここではhaarcascade_frontalface_alt2.xmlというのを使う。他との違いはあんまりよく分かってない。2)こんな感じで、簡単に顔の領域を検出してマーキングすることができる。before:after:傾き(回転)に対応するところで最近は色んなアイドルさんが自撮り画像を上げてくれてたりする。「ののた」こと奥村野乃花ちゃん。iPhoneののた可愛い。それはともかく、、こういった自撮り画像、結構な角度で傾いているものだったりする。Classifiersによる顔検出はちょっとでも傾きがあると精度が一気に変わってしまうようで、先述の例のような真正面の顔が期待できない場合はそのままではほぼ使えない。自撮りは傾いているものが多くて厳しい。以下の記事を参考に、元画像を徐々に回転したものを生成して、それぞれを対象に繰り返し検出を試みる。Qiita斜辺サイズの枠を用意して、中央に元画像を配置してそれを中心に回転行列をかけて画像を変換。2)とりあえず5°ずつのstepでやってみた結果が以下。40°まで回転させたところでようやく顔を検出している。35°のところでは全然関係ない箇所が誤検出されている。ちなみにこのへんの精度はある程度detectMultiScaleの引数を変更することで調整することもできる。25°など誤検出が増える。そこで第3引数のminNeighborsをデフォルトの3から4に増やすととなり、誤検出が消える。このへんはケースにもよるので「どの値が一番良い」みたいなものは一概には言えなそう。あと処理速度にも影響があってscaleFactorを小さくすると処理量が増大する。その検出された領域で両目を検出してみる。これはhaarcascade_eye.xmlという別のファイルを使うだけで、同じ要領でできる。35°はそもそも顔領域が変な位置で検出されている場合で、当然ながら目は見つからない。目の部分を検出できている場合もあれば全然ちがう部分を検出しまくってグロいことになっている場合もある。1°の変化もだいぶ結果が違う。言え多くの場合は目を検出できているので、例えば顔の下半分領域で検出されたものは目なはずないので無視する、とかフィルタリングはできると思う。回転行列の逆変換をかけてやれば、元画像における顔や目の中心座標が取得できる。x)が最も0に近い)ものを選択する、などするとより良い結果を得られるかな、ということでそうしてみた。