Help us understand the problem. What is going on with this article?

【入門者向け解説】openCV顔検出の仕組と実践(detectMultiScale)

概要と環境

openCVの顔検出方法について調べて試してみました。入門者向けに解説します。
以下はopenCV関連記事です。

検証環境は下記のとおりです。
00.ArchitectureopenCV.JPG

openCVの顔検出でできたこと

人物画像に対して顔検知して四角枠で囲みました。
10.Sample00.jpg

複数人でも大丈夫。すごい!
10.Sample01.jpg

変顔だって検知します!(後ろの人も検知できてます)
10.Sample02.jpg

顔検知から鼻検知に切り替えることもできます。
10.Sample03_Nose.jpg

oepnCVの顔検出の仕組み

論文や具体的なアルゴリズムを見て調べて確認していないので、以降の解説は誤りがあるかもしれません(指摘いただけたら嬉しいです)。半日程度で筆者が理解した内容です。
おそらく動画「Viola Jones face detection and tracking explained」を見れば、かなり理解が深まるでしょうが、1.5時間という長時間を悟って心が折れました・・・

顔検出方法概要

判定画像(読み込んだ画像)全体から一部を切り取って様々な基準で判定していきます。1回でも「顔でない」と判定されれば、後続の判定は行わず、次の画像の一部に対して判定器にかけていけいます。全判定をしないことにより、顔検出処理の高速化を実現しています(個々の判定精度は低いですが、多く重ねることにより全体として精度を保ちます)。
20.DetectOverview.JPG

左側の切り取りプロセスがわかりやすいように、openCVのAPIのパラメータを変えて、あえて誤検知させてみました。非常に多くの枠で顔を検知している、つまり少なくてもこれだけの枠部分は判定をしているということです。判定画像全体を切り取って個々に判定器にかけているのがわかります。
30.Sample01.many.jpg

判定方法

Harr-like検出器概要

Haar-like検出器を使って顔判定します。判定プロセスはこんな感じ。
40.HarrLike.JPG
鼻中央部分は光があたるので明るく、鼻の周辺は影ができて暗くなるため、上記の判定方法が有効です。判定単体で見ると単純で素早くできますが、その半面、判定精度は低いです。そのため多くの判定をすることで全体としての精度を高めます。
上記のような判定に使うHaar-like検出器は大きく3種類があります。
HarrLike

判定方法の弱点

弱点として正面の顔でないと検出精度が著しく落ちます。例えば、下図のような横顔は検出できませんでした。
30.Sample02Angles.jpg

また、顔を回転させても検出できませんでした。
30.Sample02.angles.JPG

Pythonコード

以下のコードを使って検証しました。試行錯誤の跡も残しています。最後に載せているリンクからそのままコピペした部分も多いです。学習済モデル実行時に指定できるコードは記事「openCVの顔検出でパラメータを指定して手っ取り早く検出精度を高める」に書いています。また、フォルダにある複数画像を読み込んで、検出した顔部分を切り出して保存するコードは記事「openCVで複数画像ファイルから顔検出をして切り出し保存」を参照ください。

import cv2

# 分類器ディレクトリ(以下から取得)
# https://github.com/opencv/opencv/blob/master/data/haarcascades/
# https://github.com/opencv/opencv_contrib/blob/master/modules/face/data/cascades/

cascade_path = "./models/haarcascade_frontalface_default.xml"

# 他のモデルファイル(参考)
#cascade_path = "./models/haarcascade_frontalface_alt.xml"
#cascade_path = "./models/haarcascade_frontalface_alt2.xml"
#cascade_path = "./models/haarcascade_frontalface_alt_tree.xml"
#cascade_path = "./models/haarcascade_profileface.xml"
#cascade_path = "./models/haarcascade_mcs_nose.xml"

# 使用ファイルと入出力ディレクトリ
image_file = "test.jpg"
image_path = "./inputs/" + image_file
output_path = "./outputs/" + image_file

# ディレクトリ確認用(うまく行かなかった時用)
#import os
#print(os.path.exists(image_path))

#ファイル読み込み
image = cv2.imread(image_path)

#グレースケール変換
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#カスケード分類器の特徴量を取得する
cascade = cv2.CascadeClassifier(cascade_path)

#物体認識(顔認識)の実行
#image – CV_8U 型の行列.ここに格納されている画像中から物体が検出されます
#objects – 矩形を要素とするベクトル.それぞれの矩形は,検出した物体を含みます
#scaleFactor – 各画像スケールにおける縮小量を表します
#minNeighbors – 物体候補となる矩形は,最低でもこの数だけの近傍矩形を含む必要があります
#flags – このパラメータは,新しいカスケードでは利用されません.古いカスケードに対しては,cvHaarDetectObjects 関数の場合と同じ意味を持ちます
#minSize – 物体が取り得る最小サイズ.これよりも小さい物体は無視されます
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))

#print(facerect)
color = (255, 255, 255) #白

# 検出した場合
if len(facerect) > 0:

    #検出した顔を囲む矩形の作成
    for rect in facerect:
        cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)

    #認識結果の保存
    cv2.imwrite(output_path, image)

使用した学習済モデルのファイル取得

Git Hubから顔検出鼻検出の学習済モデルファイルを取得して使っています。

検証していませんが、どの学習済モデルを使うかはstackoverflowと記事「OpenCV 使用可能なCascadeClassifierの種類と効果」が参考になります。

顔検出をするメソッド"cascade.detectMultiScale"

顔検出に使っているのはメソッド"cascade.detectMultiScale"です。公式サイトで見るとわかりますが、類似メソッドとして"cascade.detectMultiScale2"と"cascade.detectMultiScale3"がありますが、パラメータが違うのみで、基本的な処理は変わらないようです。stackoverflowで聞きました。
パラメータ"scaleFactor"と"minNeighbors"が検出精度を高める上で非常に重要です。筆者の試行錯誤は記事「openCVで効率的に大量画像を顔検出するためのtips」に書き留めています。
以下の情報を参考にして理解しました。

参考リンク

今回、勉強に使ったサイトをリンクとして載せておきます。

サイト コメント
Haar Cascadesを使った顔検出 公式チュートリアルの日本語訳
サルでもわかる顔検出の原理 顔検出の原理についてわかりやすい解説あり
顔の切り出しと認識 スライド形式の顔検出わかりやすい説明あり
OBJECT DETECTION : FACE DETECTION USING HAAR CASCADE CLASSFIERS コードを交えた物体検出の詳しい説明(英語)
Heroku + OpenCVで簡易顔検出API 顔を傾けて精度を高める方法あり
Python+OpenCV で顔検出 - OpenCV に付属の評価器を試す モデルとパラメータを変えた検証結果あり
python+OpenCVで顔認識をやってみる プログラムのコピペ元
FukuharaYohei
気の向いたままにいろいろと書きます。 仕事はSAP関連で、HANA、Fiori、SAPUI5、BusinessObjectsなどいろいろやっています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした