OpenCV3で顔認識 精度をテスト

前回なんとかPython3+OpenCV3の環境を用意しました。

さっそく顔認識のテストを行います。果たしてどれだけの精度か?

顔認識の仕組み

まずは、顔認識の仕組みをおおざっぱに理解したいと思います。

顔を認識するには、顔かどうか分類する特徴データが必要となります。この特徴データを「分類器」と呼ぶようです。

分類器と照らし合わせて、顔かどうか判断します。

分類器を作るために、人間の顔の特徴を機械に学習させないといけません。
これを機械学習と呼びますが、顔のようなメジャーなものは、学習済みデータが手に入ります。

使用する分類器

今回テストで使う分類器は、OpenCVデフォルトの2つです。

  • haarcascade_frontalface_default.xml・・・正面顔
  • haarcascade_eye.xml・・・目

PCで「haarcascade_frontalface_default.xml」を検索すると、どこかで見つかるかと思います。

分類器は他にも、全身や笑顔などが用意されています。

感情取得は面白そうです。精度次第ですが・・・。

ディレクトリ構成

顔認識のテストを始めます。

前回用意した「C:\FACE」内に下記の構成でフォルダとファイルを用意します。

  • haarcascades・・・分類器のフォルダ
  • img・・・テスト用の画像フォルダ
  • rectangle.py・・・顔認識して四角で囲うプログラム

分かりやすいので、分類器のフォルダ「haarcascades」を、C:\FACEにコピーしてきました。
使用するのは、顔正面と目の分類器だけです。

テスト画像の用意

imgフォルダには、テストする画像を6枚いれました。

GATAGフリー画像・写真素材集より、パブリックドメインのものを使わせて頂きます。

顔認識のPythonプログラム

rectangle.pyは、「OpenCVを使った顔認識」で紹介されているコードを使わせて頂きました。

私のディレクトリ構成に書き換えただけですが、分かりやすいように掲載します。

import cv2

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

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

# グレースケール変換
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]
    # 顔画像(カラースケール)
    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()

4行目、5行目で分類器の読み込み。相対パスで読み込んでいます。

8行目でテスト画像の読み込み。ここのファイル名を書き換えながら、テストをしていきます。

テスト1 正面を向いた西洋人

まずは、顔認識が容易そうな画像から。

私の仮説(思い込み)では、西洋人の機械学習量の方が多く、認識されやすいのではと考えています。

さらに背景も白単色。服もシンプルな画像で実行。

おお!お?

顔も目も、すべて認識しています。

しかし、3か所顔ではないところを誤認しています。

けっこう判定がゆるいのか?

テスト2 赤ちゃん

続いて、顔の特徴が違う赤ちゃんを認識できるかテストです。

認識できれば、赤ちゃんが寝返りで窒息しないよう、見守りで使えそうです。

お、認識できました。・・・あれ?

緑の四角は目なのですが、赤ちゃんに4か所目が認識されてます。

お母さんも3か所。

通常は1つの顔に、目は2つしかないことを、機械に教えてあげないといけないようです。

テスト3 東洋人

次に、日本では実用的な、東洋人の顔認識テストです。

顔はだいたい認識されています。目は、けっこう開いていないと認識されないようです。

右手前の男の子の顔が認識されていません。
正面の女の子の手が邪魔で、首を傾けていますが、これくらいで認識精度は落ちるようです。

また、真ん中後ろの女性と、一番右の女性は、顔が2回認識されています。

テスト4 背景ごちゃごちゃ+犬

機械に厳しくしていきます。

今までと違い、背景がごちゃごちゃした画像で試します。

さらに犬までいるので、誤認だらけになってしまいそうですが・・・

あれ?予測の逆。

判定がシビアになり、認識された顔の数が減り、誤認はゼロ。

目は一つも認識されない事態に。

顔一つあたりの解像度が低すぎたかな?

テスト5 横顔

今度は横顔をどれだけ判断できるかテストします。

いつでも正確に正面を向いてくれるほど、人間は甘くありません。

おっ!正面顔の分類器を使っているのに、意外といけます。

お母さんはさすがに無理ですが、女の子はこの角度でも認識されました。

男の子も目をつむっているのに、一つは目として認識されています。

テスト6 見上げた横顔

先ほどの女の子と同じくらいの横顔で、見上げた状態の顔認識テストです。

心霊写真検出!?

正面顔の分類器に、この画像の認識は酷だったのでしょう。

横顔分類器に変更します。

rectangle.pyの4行目を「haarcascade_profileface.xml」に変更。

あれ?

何も認識しない。プログラムの問題?

検証のため、再びテスト5の女の子で確認。

認識します。盛大に誤認もします。

ということで、見上げた顔が認識されにくいことになります。

テスト3でも感じましたが、傾いた顔の認識が弱いです。

精度を求めるのは簡単ではない

遊びでは良いですが、OpenCVデフォルトの分別器をそのまま使って顔認識は厳しい印象です。

精度を求める場合、深層学習(ディープラーニング)の分野まで進む必要があるかもしれません。

人間ってすごい

小学生みたいな感想ですが、今回のテストで感じたことは、人間ってすごい!

視覚情報をリアルタイムで処理して、人の顔を認識するというのは、途方もなく高度な処理なんだと思います。

人間のようなリアルタイム高精度処理はできませんが、次回、Webカメラを使った動画の顔認識を試してみます。
やっぱり分類器自作を試みます。

Webカメラによるリアルタイム顔認識は、他サイトのコードを持ってきただけで終わってしまったので。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)