どこにでもいる30代SEの学習ブログ

主にプログラミング関連の学習内容。読んだ本の感想や株式投資についても書いてます。

【Python】Face Recognitionで顔検出

「Face Recognition」というPythonの顔認識ライブラリを使い、顔検出を行いました。

中身は「dlib」なので、顔検出の精度は「dlib」と変わりませんが、顔認識に用途を絞ってより使いやすく作られています。

Face Recognition — Face Recognition 1.4.0 documentation

[1] Face Recognitionのインストール

pip3 install face_recognition --user

前提として「dlib」のインストールが必要です。インストール方法は、以前の記事で紹介した内容の通りです。

https://predora005.hatenablog.com/entry/2021/08/30/190000predora005.hatenablog.com

[2] ソースコード

公式のExample2つを参考にしています。検出期にCNNを使うか否か以外は同じ内容です。

顔検出だけであれば「dlib」のみインポートで十分ですが、検出領域の表示等で「OpenCV」を使用しています。

[2-1] HOG特徴量ベースの顔検出

import os
import cv2
import face_recognition

# 顔検出する画像のファイルリスト
filelist = [ 'sample1.jpg',  'sample2.jpg', 'sample3.jpg']
imgdir = os.path.join(os.path.expanduser('~'), 'img')
filepaths = [os.path.join(imgdir, file) for file in filelist]

# HOG特徴量ベースの顔検出
for filepath in filepaths:
    # 画像読み込み
    image = face_recognition.load_image_file(filepath)
    
    # HOGベースモデルの顔検出実行
    face_locations = face_recognition.face_locations(image)
    
    # 検出した領域を表示
    print("------------------------------")
    print("I found {} face(s) in this photograph.".format(len(face_locations)))
    for face_location in face_locations:
        top, right, bottom, left = face_location
        print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
        
    # 顔検出した領域を短形表示した画像を保存
    save_face_located_image(filepath, face_locations, 'hog')

[2-2] CNNモデルの顔検出

HOG特徴量ベースの検出と変わるのはface_recognition.face_locationsの引数のみです。model="cnn"と指定することでCNNによる顔検出が行われます。

number_of_times_to_upsampleはアップサンプリングの回数です。デフォルトは1です。

# ここまではHOG特徴量ベースの検出と同じ

# 学習済みCNNモデルによる顔検出
for filepath in filepaths:
    
   # 画像読み込み(HOG特徴量ベースの検出と同じ)
    image = face_recognition.load_image_file(filepath)
    
    # CNNベースモデルの顔検出実行
    face_locations = face_recognition.face_locations(
        image, number_of_times_to_upsample=1, model="cnn")
    
    # 検出した領域を表示(HOG特徴量ベースの検出と同じ)
    print("------------------------------")
    print("I found {} face(s) in this photograph.".format(len(face_locations)))
    for face_location in face_locations:
        top, right, bottom, left = face_location
        print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
        
    # 顔検出した領域を短形表示した画像を保存
    save_face_located_image(filepath, face_locations, 'cnn')

[2-3] 顔検出した領域を短形表示した画像を保存

上記ソースコードで使用したsave_face_located_imageソースコードは以下の通りです。

画面に表示できる環境であれば、わざわざ保存せず表示する方が簡単です。dlib, Pillow, OpenCVなどを使えば表示することは可能です。

def save_face_located_image(filepath, face_locations, prefix):
    # 保存用の画像データを準備
    save_img = cv2.imread(filepath)
    
    # 検出した範囲を保存用画像に短形表示
    for face_location in face_locations:
        y1, x2, y2, x1 = face_location
        cv2.rectangle(save_img, (x1, y1), (x2, y2), color=(0,0,255), thickness=4)
        
    # 検出領域を示した画像を保存
    filename = os.path.basename(filepath)
    filedir = os.path.dirname(filepath)
    save_filename = prefix + '_' + filename
    save_imgpath = os.path.join(filedir, save_filename)
    cv2.imwrite(save_imgpath, save_img)

[3] 顔検出の結果

中身が「dlib」なので検出精度は変わりません。以前紹介した記事と同じ画像で検出を行っても、同じ結果になります。

以前紹介したものとは異なる画像で検出を行ってみます。

[3-1] HOG特徴量ベースの検出結果

f:id:predora005:20210809222222j:plain <青空の下、スマホで記念写真3 - No: 315218|写真素材なら「写真AC」無料(フリー)ダウンロードOK>

f:id:predora005:20210809222230j:plain <jswashburnによるPixabayからの画像>

f:id:predora005:20210809222234j:plain <Joseph MuciraによるPixabayからの画像>

[3-2] CNNモデルの検出結果

f:id:predora005:20210809222427j:plain <青空の下、スマホで記念写真3 - No: 315218|写真素材なら「写真AC」無料(フリー)ダウンロードOK>

f:id:predora005:20210809222438j:plain <jswashburnによるPixabayからの画像>

f:id:predora005:20210809222517j:plain <Joseph MuciraによるPixabayからの画像>

終わりに

「Face Recognition」は「dlib」ベースです。「dlib」と精度は変わりませんが、より簡単に顔検出ができるようになっていました。

顔検出や顔認識をするのであれば「Face Recognition」を使うのが、精度も良くお手軽だと思います。

参考文献

画像の出典