LoginSignup
0
0

More than 3 years have passed since last update.

OpenCV Haar Cascades で顔認識

Posted at

はじめに

  • 最終的なWebアプリケーションに至る作業なので、資料を公開することにしました。
  • なので、基本的な話のみになります。
  • ソース一式は ここ です。
  • 参考

ライブラリのインストール

  • Ubuntu なら $ apt install python3-opencv でインストールする場合もあると思います。
  • また、最終的なWebアプリケーションの環境は、Heroku を想定しています。
  • Heroku の場合は、Ubuntu を利用できますが、python3-opencv は、うまく動作しません。
  • 下記の pipopencv-python なら、最新バージョン、マルチコアの利用など、良い事が多いです。
$ pip install opencv-python

設定ファイル config.py

  • ダウンロードした画像ファイルのフォルダ、顔認識した画像ファイルのフォルダを指定しています。
  • 顔認識に利用する Haar Cascades xml ファイルの場所を指定します。
  • CLASSES を利用して、該当フォルダの画像を順次処理します。
$ cat config.py

CLASSES = [
    '安倍乙',
    '石原さとみ',
    '大原優乃',
    '小芝風花',
    '川口春奈',
    '森七菜',
    '浜辺美波',
    '清原果耶',
    '福原遥',
    '黒島結菜'
]

BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATA_PATH = os.path.join(BASE_PATH, 'data')
LINK_PATH = os.path.join(DATA_PATH, 'link')
DOWNLOAD_PATH = os.path.join(DATA_PATH, 'download')
FACE_PATH = os.path.join(DATA_PATH, 'face')

HAARCASCADE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'haarcascade_frontalface_default.xml')

haarcascade_frontalface_default.xml

  • 以下から xml ファイルダウンロードします。
$ wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml

顔認識プログラム save_face_image.py

ダウンロード画像の一覧の取得、Haar Cascade の読み込み等

  • query には、CLASSES が順次与えられます。
  • ダウンロード画像のパスの確認、顔画像のパスの作成をします。
  • Haar Cascade を読み込みます。
  • glob でダウンロード画像の *.jpeg を検索し、一覧化します。
def detect(query):
    """画像の読み込み、顔画像の検出、顔画像の保存."""

    download_path = os.path.join(DOWNLOAD_PATH, query)
    if not os.path.isdir(download_path):
        print('no download path: {}'.format(download_path))
        return

    os.makedirs(os.path.join(FACE_PATH, query), exist_ok=True)

    face_cascade = cv2.CascadeClassifier(HAARCASCADE_PATH)

    download_list = glob.glob(os.path.join(download_path, '*.jpeg'))
    download_list.sort()

顔認識

  • ダウンロード画像を順次処理します。
  • 画像はカラーからグレースケールに変換し、Haar Cascade で顔認識を実施します。
  • scaleFactor は、画像から顔認識をする時に、画像を異なるサイズに変更し、複数回顔認識をするための値です。
  • scaleFactor が小さいと、顔以外を検知したり、時間がかかったりします。逆に、大きい値だと、検知出来なかったりします。
  • 初期値は、1.1 ですが、誤検知と非検知を鑑み、1.2 にしています。
  • minNeighbors は、上記の scaleFactor に関連があります。
  • scaleFactor は、画像の同じ箇所を複数回確認し、検知することになります。何回検知した時、顔認識したことにするかを minNeighbors で指定しています。この値が大きいと、複数回検知しないと、顔認識したと見なされないので、見落としが発生します。
  • 今回は、3 にしました。この値は、デフォルト値です。忘れない様に、あえて指定しています。
  • この値の調整は、状況に応じて調整が必要なので、難しいですね。。。
    for download in download_list:

        img = cv2.imread(download)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3)

        if len(faces) < 1:
            print('query: {}, download: {}, face num: 0'.format(query, os.path.basename(download)))
            continue

顔画像の保存

  • 顔画像の位置元に、画像を取り出し、顔画像のフォルダに保存します。
  • ファイル名は、ダウンロード画像を元にしています。
  • 例えば、ダウンロード画像が 0001.jpeg なら 顔画像は 0001-0001.jpeg になります。
  • 複数人の顔画像が認識されるので、0001-0002.jpeg 0001-0003.jpeg と言う感じで保存しています。
        for num, (x, y, w, h) in enumerate(faces, start=1):
            face = img[y:y+h, x:x+w]

            filename = os.path.join(FACE_PATH, query, os.path.basename(download).split('.')[0] + '-{:04d}.jpeg'.format(num))
            cv2.imwrite(filename, face)
            print('query: {}, download: {}, filename: {}'.format(query, os.path.basename(download), os.path.basename(filename)))

顔画像の例

  • 以下の様な感じです。誤検知がありますね。この後が辛い。。。

image.png

おわりに

  • 顔認識を実施しました。
  • 次回は、顔認識の簡易管理アプリと誤検知の削除をする予定です。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0