Python
画像処理
OpenCV

OpenCVを使った顔認識(Haar-like特徴分類器)

More than 1 year has passed since last update.

Haar-like特徴分類器

 「Haar-like特徴を用いたブースティングされた分類器のカスケード」とは、Haar-likeとよばれる明暗で構成される矩形のパターンを検出に使う手法です。Haar-like特徴と対象画像を重ね合わせ、パターンがあるかないかを判定します。
 haar.png

OpenCVには以下のHaar-like特徴分類器があらかじめ用意されています。
[OpenCV Install Dir]/Library/etc/haarcascades/

ファイル名 内容
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml 眼鏡
haarcascade_frontalcatface.xml 猫の顔(正面)
haarcascade_frontalcatface_extended.xml 猫の顔(正面)
haarcascade_frontalface_alt.xml 顔(正面)
haarcascade_frontalface_alt2.xml 顔(正面)
haarcascade_frontalface_alt_tree.xml 顔(正面)
haarcascade_frontalface_default.xml 顔(正面)
haarcascade_fullbody.xml 全身
haarcascade_lefteye_2splits.xml 左目
haarcascade_licence_plate_rus_16stages.xml ロシアのナンバープレート(全体)
haarcascade_lowerbody.xml 下半身
haarcascade_profileface.xml 顔(証明写真)
haarcascade_righteye_2splits.xml 右目
haarcascade_russian_plate_number.xml ロシアのナンバープレート(数字)
haarcascade_smile.xml 笑顔
haarcascade_upperbody.xml 上半身

今回は、OpenCVのHaar-like特徴分類器を使って、顔認識をしてみます。

OpenCV

OpenCV(Open Source Computer Vision Library)はBSDライセンスの映像/画像処理ライブラリ集です。画像のフィルタ処理、テンプレートマッチング、物体認識、映像解析、機械学習などのアルゴリズムが多数用意されています。

■ OpenCVを使った動体追跡の例 (OpenCV Google Summer of Code 2015)
https://www.youtube.com/watch?v=OUbUFn71S4s

■ インストールと簡単な使い方はこちら
OpenCV 3(core + contrib)をPython 3の環境にインストール&OpenCV 2とOpenCV 3の違い&簡単な動作チェック
  ★ モーションテンプレートを実行するために、core + opencv_contrib をインストールしてください。

■ 静止画像のフィルター処理についてはこちら
OpenCVでエッジ検出してみる
OpenCVで各種フィルター処理をする(グラディエント、ハイパス、ラプラシアン、ガウシアン)
OpenCVで特徴点を抽出する(AgastFeature, FAST, GFTT, MSER, AKAZE, BRISK, KAZE, ORB, SimpleBlob)

■ 動画ファイルの処理についてはこちら
OpenCVで動画をリアルタイムに変換してみる
OpenCVでWebカメラ/ビデオカメラの動画をリアルタイムに変換してみる
OpenCVでオプティカルフローをリアルタイムに描画する(Shi-Tomasi法、Lucas-Kanade法)
OpenCVを使った物体追跡(マウスで指定した特徴点をLucas-Kanade法で追跡する
OpenCVを使ったモーション テンプレート解析(リアルタイムに物体とその動く方向を認識する)

プログラム

流れは、下記のようになっています。
1. cv2.CascadeClassifier([Haar-like特徴ファイル.xml])でHaar-like特徴分類器を作成
2. Haar-like特徴分類器に対して画像を指定
3. 画像に対して検出した領域を矩形で囲む

face.py
import cv2

# Haar-like特徴分類器の読み込み
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')

# イメージファイルの読み込み
img = cv2.imread('face.png')

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

# 顔を検知
faces = face_cascade.detectMultiScale(gray)
for (x,y,w,h) in faces:
    # 検知した顔を矩形で囲む
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
    # 顔画像(グレースケール)
    roi_gray = gray[y:y+h, x:x+w]
    # 顔g増(カラースケール)
    roi_color = img[y:y+h, x:x+w]
    # 顔の中から目を検知
    eyes = eye_cascade.detectMultiScale(roi_gray)
    for (ex,ey,ew,eh) in eyes:
        # 検知した目を矩形で囲む
        cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

# 画像表示
cv2.imshow('img',img)

# 何かキーを押したら終了
cv2.waitKey(0)
cv2.destroyAllWindows()

実行結果

こんな画像だと、こんな感じで認識します。
顔は全て認識しているものの、目はぼんやりとした画像のためかあまり認識してくれていません。
result.png

こんな画像だと、こんな感じで認識します。
顔全体は、かなり認識してくれます。一方、目は視線が正面を向いていれば認識してくれています。
result12.png

目や横顔などの検出パターンをある程度把握していけば、目線や目線の先にある物を推測することもできそうです。