grasys blog

Pythonで手軽に顔認識をやってみる(face-recognition)

はじめまして!エンジニアのUemaです。

近年では、スマホのロックの解除や入館時の認証など様々なことに顔認識の技術が使われています。

顔認識を利用するには機械学習、画像処理や数学などの様々な知識が必要で学習コストがかかり、顔認識を使ってアプリケーションを作ってみたいと考えている人もなかなか手が出ないと思います。

そんな人に朗報です!

手軽に顔認識を行えるface-recognitionというPythonライブラリが存在します!

今回は顔認識の入り口として、face-recognitionを実際に使ってみたいと思います。

face-recognitionとは

Pythonコードやコマンドラインで手軽に顔を検出・認識することができるライブラリです。face-recognitionの顔認識モデルは99%の正解率を記録しているそうです。

インストール(mac)

Pythonとhomebrewがインストールされていることが前提です。(Pythonのバージョンはなんでも良いですが、今回はPython 3.10.9で実施しています。)

face_recognitionで使用しているdlibライブラリをインストールすることに必要なcmakeをインストールする。

$ brew install cmake

face_recognitionライブラリをインストールする。

$ pip install face_recognition

顔を検出する

画像を読み込み、face_recognitionのface_locationsを使用すると検出した顔の座標が取得できます。

import face_recognition
from PIL import Image, ImageDraw

# 画像を読み込む
load_image = face_recognition.load_image_file("images/faces.jpg")

# 認識させたい画像から顔検出する
face_locations = face_recognition.face_locations(load_image)

pil_image = Image.fromarray(load_image)
draw = ImageDraw.Draw(pil_image)

# 検出した顔分ループする
for (top, right, bottom, left) in face_locations:
    # 顔の周りに四角を描画する
    draw.rectangle(((left, top), (right, bottom)),
                   outline=(255, 0, 0), width=2)

del draw

# 結果の画像を表示する
pil_image.show()

下記の画像を読み込みます。

実行結果は、下記の画像です。

きちんと顔を検出して、私の顔とスマホ内の顔を四角で囲んでいることがわかります。

WBEカメラから顔認識を行う

WEBカメラの使用でOpenCVが必要になるため、ライブラリをインストールする。

$ pip install opencv-python

実装の流れとしては、下記の通りです。

  1. 認識したい顔の画像を読み込み、顔の特徴値を取得する。
  2. WBEカメラから1フレーム読み込み、顔を検出しそれぞれの特徴値を取得する。
  3. 検出した顔の特徴値と認識したい顔の特徴値を比較する。
import face_recognition
import cv2
import numpy as np


video_capture = cv2.VideoCapture(0)

# 画像を読み込み、顔の特徴値を取得する
hasegawa_image = face_recognition.load_image_file("images/hasegawa.jpg")
hasegawa_face_encoding = face_recognition.face_encodings(hasegawa_image)[0]
kanba_image = face_recognition.load_image_file("images/kanba.jpg")
kanba_face_encoding = face_recognition.face_encodings(kanba_image)[0]
uema_image = face_recognition.load_image_file("images/uema.jpg")
uema_face_encoding = face_recognition.face_encodings(uema_image)[0]

known_face_encodings = [
    hasegawa_face_encoding,
    kanba_face_encoding,
    uema_face_encoding,
]
known_face_names = [
    "Hasegawa",
    "Kanba",
    "Uema",
]

while True:
    # Webカメラの1フレームを取得、顔を検出し顔の特徴値を取得する
    _, frame = video_capture.read()
    rgb_frame = frame[:, :, ::-1]
    face_locations = face_recognition.face_locations(rgb_frame)
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)

    # 1フレームで検出した顔分ループする
    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        # 認識したい顔の特徴値と検出した顔の特徴値を比較する
        matches = face_recognition.compare_faces(
            known_face_encodings, face_encoding)
        name = "Unknown"
        face_distances = face_recognition.face_distance(
            known_face_encodings, face_encoding)
        best_match_index = np.argmin(face_distances)
        if matches[best_match_index]:
            name = known_face_names[best_match_index]

        # 顔の周りに四角を描画する
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # 名前ラベルを描画
        cv2.rectangle(frame, (left, bottom - 35),
                      (right, bottom), (0, 0, 255), cv2.FILLED)
        cv2.putText(frame, name, (left + 6, bottom - 6),
                    cv2.FONT_HERSHEY_TRIPLEX, 1.0, (255, 255, 255), 2)

    # 結果を表示する
    cv2.imshow('WebCam', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()

社長のHasegawaさん、経営企画のKanbaさんに協力していただき、下画像の顔を登録してWEBカメラから顔認識します。

Hasegawaさん
Kanbaさん
Uema(私)

結果は、きちんと顔認識することができました。

別の画像でも顔を判別することができ、メガネを外した状態でも判別することができました。

終わりに

機械学習などの知識があまりなくても簡単に顔認識を行うことができました。

実装した顔認識のプログラム以外にも、たくさんのサンプルがあるので、興味がある方は実際に動かしてみてください。

顔検出や顔認識について内部の動作原理など知らなくても実装できますが、知っておいて損はないのでさらなる理解を深めたい場合はこちらを参照してください。


P.S.

Raspberry Pi を使い、顔認証からパスワード入力までやってみたブログも公開しています。

ご興味があれば、ぜひご覧ください!

参考

Face Recognition(GitHub)

face-recognition(PyPI)


採用情報
お問い合わせ