Atom's tech blog

OpenCVで顔認証をサンプルコードを参考に作ってみた(顔認証モデルファイル作成編)

顔認証モデルファイル作成の概要

  • 顔認証するために学習する人物毎に番号をつけて顔画像を保存する
  • 保存した顔画像ファイルの全員分データを一つのモデルファイルとして作成する

モデルファイル作成方法(ソースファイル説明)は以下の流れ

  • カメラから顔をキャプチャー
  • キャプチャーした後は顔認識用のカスケードファイル(haarcascade_frontalface_alt2.xml)を使用して顔認識する
  • 顔認識した画像から顔の部分を抽出し、画像ファイルに保存する
  • 最後に保存している複数人の顔画像からYAMLファイル(モデルファイル)を作成する

コメント

  • 掲載したソースは「Mac」で動作確認済み *「ラズパイ」/「Tinkerboard」でも動作可能
  • USBカメラのVideoポート変更必要
  • 使った各種バージョンは以下
  • MacOS Mojave / python3.5.6 / Opencv3.4.2 / VS Code1.38.1

モデルファイルサンプル画像

・画像ファイルから顔認証モデルファイルを作成する際に使用した画像(サンプル)

(注)下記のソースコードはカメラからキャプチャーしている

f:id:iAtom:20201007161207j:plain

ファイル構成

  • ./data_xml/ # カスケードファイルを格納しているフォルダ
  • ./image_data/ # キャプチャーした画像ファイルを保存するフォルダ
  • ./trainer/ # モデルファイルをYAMLファイルとして保存するフォルダ
  • face_datamake.py # モデルファイルを作成Pythonファイル(下のソースコード

ソースコード

# -*- coding: UTF-8 -*-
import cv2
import os
import numpy as np
from PIL import Image

# モデル画像データ枚数取得変数初期化
sample_cnt = 0

###############################
# VideoCapture用インスタンス生成 #
###############################
cap = cv2.VideoCapture(0)

###############################
# 画像サイズをVGAサイズに変更する  #
###############################
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) 
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) 

#######################################################################
# 顔検出を認識する カスケードファイルは「haarcascade_frontalface_alt2.xml」 #
# カスケードファイルは以下からローカルにダウンロードしておく                    #
# <https://github.com/opencv/opencv/tree/master/data/haarcascades>    #
#######################################################################
face_detector = cv2.CascadeClassifier('/Users/local/source/opencv/face_recognition/data_xml/haarcascade_frontalface_alt2.xml')

#######################################################
# モデル画像用データから顔認証データymlファイル作成するメソッド  #
# このファイルを顔認証デートのモデルファイルとして使用する     #
#######################################################
def image_learning_make_Labels():

    # リスト保存用変数
    face_list=[]
    ids_list=[]

    # モデル画像データ保存領域パス情報
    path = '/Users/local/source/opencv/face_recognition/image_data'
    # Local Binary Patterns Histogram(LBPH)アルゴリズム インスタンス
#    recognizer = cv2.face.createLBPHFaceRecognizer()
    recognizer=cv2.face_LBPHFaceRecognizer.create()

    # モデル画像ファイルパスを全て取得
    imagePaths = [os.path.join(path,f) for f in os.listdir(path)]
 
    # モデル画像ファイル分ループ
    for imagePath in imagePaths:

        # グレースケールに変換
        PIL_img = Image.open(imagePath).convert('L')
        img_numpy = np.array(PIL_img,'uint8')

        # UseriDが入っているファイル名からUserID番号として取得
        id = int(os.path.split(imagePath)[-1].split(".")[1])
        # 物体認識(顔認識)の実行
        faces = face_detector.detectMultiScale(img_numpy)

        # 認識した顔認識情報を保存
        for (x,y,w,h) in faces:
            face_list.append(img_numpy[y:y+h,x:x+w])
            ids_list.append(id)

    print ("\n Training Start ...")
    ##############################
    # トレーニングスタート                 #
    ##############################
    recognizer.train(face_list, np.array(ids_list))

    #####################################
    # モデルファイルを.ymlファイルに保存する  #
    #####################################
    recognizer.save('/Users/local/source/opencv/face_recognition/trainer/trainer.yml') 

    # 顔種類を標準出力
    print("\n User {0} trained. Program end".format(len(np.unique(ids_list))))


#####################################
# 顔認証したい人物の通し番号を入力させる
#####################################
User_id = input('\n User Id Input <ex:001> >>>  ')
print("\n Face capture Wait ............")

####################################
#  モデル画像データ取得と保存
####################################
while(True):
   
    # カメラで顔データを取得する
    ret, img = cap.read()
    # 画像をグレースケールに変換する
    image_pil = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # NumPyの配列に格納
    gray = np.array(image_pil, 'uint8')
    # Haar-like特徴分類器で顔を検知
    faces = face_detector.detectMultiScale(gray)
    # モデルファイル作成
    for (x,y,w,h) in faces:
        # 顔部分を切り取り
        cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)     
        sample_cnt += 1

        # 画像ファイル名にUSERIDを付与して保存
        cv2.imwrite("/Users/local/source/opencv/face_recognition/image_data/User." + str(User_id) + '.' + str(sample_cnt) + ".jpg", image_pil[y:y+h,x:x+w])
        # 画像データを画面表示
        cv2.imshow('image', img)

    # 認証モデル画像を10枚
    if sample_cnt >= 10:
         break

print("\n Face capture End ")
########################
# モデルファイル作成
########################
image_learning_make_Labels()

### カメラ解放 ###
cap.release()
cv2.destroyAllWindows()