Pythonで簡単に顔認識実装! ~face-recognition~

プログラミング・AI
記事内に広告が含まれています。

昨今、入国審査の本人確認やスマホのロック解除に顔認識を活用したシステムが私たちの身の回りで活躍しています。

こうした技術を活用して面白いものを作れないかな~と思い、まずは顔認識について勉強していたところ、カスケード分類器など既に作りこまれたモデルがあることがわかりました。

こうえんじ
こうえんじ

それって、データセットを用意して学習させたモデルを用意しなくて、顔認識は実装できるのでは?

と疑問に思い、実装方法を調べていたところ、pythonのライブラリを用いた簡単な方法が以下のリンクで紹介されていました。

GitHub(face-recognition)

pythonやAIについて初心者の私でも実装できそうな内容だったので、実際に実装してみました。

(何ならハードウェアエンジニアなので、普段プログラミングしていません)

以降、Windows環境で簡単に顔認識を実装できるpythonのライブラリ「face-recognition」について、実際に実装した感想を述べていきたいと思います。

この記事では、以下の内容について記載しています。

  • Windows環境でpythonライブラリ「face-recognition」を用いたプログラムの実装
  • open-cvと組み合わせたリアルタイム顔認識

さあ、やっていきましょう!

face-recognitionとは

face-recognitionとは、pythonやコマンドラインで、簡単に顔認識を実装できるライブラリです。

dlib(顔の器官の検出が得意なC++のオープンソースライブラリ)のディープラーニングを用いた高精度な顔認識を実装できるライブラリで構築されていて、あるベンチマークでは正解率99%をたたき出したライブラリです。

face-recognitionのインストール

face-recognitionのインストールにあたり、MacとWindowsで若干手順が違うので気を付けてください。

本記事では、Windowsの手順について述べていきますので、以下に前提をまとめます。

前提条件

  • Windows 10 64bit
  • Python ver. 3.9.13
  • WEBカメラがついている

あまりVersionが古いと後述するリアルタイム検出で必要なopencvが動作しない場合があるので避けた方がいいです。

説明する手順は以下の通りです。

インストール手順

  1. CMakeのインストール
  2. Visual Studioのインストール
  3. dlibのインストール
  4. face-recognitionのインストール

CMakeのインストール

dlibはCベースのプログラムであるため、CMakeをインストールします。

ダウンロードページ(https://cmake.org/download/)で「Windows x64 Installer」をダウンロードします。

ダウンロードしたファイルを実行し、「Next」ボタン。

ライセンス規約に同意。

ここで、環境変数PATHを通すか聞かれますので、”Add CMake to the system PATH for the current user”を選択。

初期設定は「環境変数パスを追加しない」になっていますが、このまま進めると後でパスを通す必要が出てくるので気を付けてください。

続いてインストールするフォルダを選択し、インストール。

これでCMakeのインストールは完了です。

Visual Studioのインストール

続いて、コンパイラをインストールします。

今回はVisual Studio Communityに付属するコンパイラを使用します。

こちらのMicrosoftのサイトからVisual Studioのインストーラーをダウンロードします。

インストーラーを起動し、以下のようにチェックボックスにチェックを入れてインストールします。

以上で、コンパイラのインストールが完了です。

dlibのインストール

dlibのインストールの前にpython環境にCMakeをインストールします。

コマンドプロンプトを立ち上げ、以下のコマンドを入力。

pip install cmake

続いて、dlibをインストールします。

pip install dlib

以上でdlibのインストールは完了です。

face-recognitionのインストール

いよいよ最後の手順です。

以下のコマンドを入力して、face-recognitionをインストールします。

pip install face-recognition

以上で、開発環境の準備が完了です!お疲れさまでした。

顔を検出する

実際に顔を検出してみます。

grasys blog 「Pythonで手軽に顔認識をやってみる(face-recognition)」uema氏のサンプルコードを走らせてみます。

用意した画像はこちら。

プログラムを実行すると、、、

このようにたくさんの人が密集している写真でも顔認識ができていることがわかります。

無事face-recognitionの導入が完了できているようです。

open-cvと組み合わせたリアルタイム顔認識

WEBカメラを用いてリアルタイムに顔認識を行うプログラムを実装します。

こちらもgrasys blog 「Pythonで手軽に顔認識をやってみる(face-recognition)」uema氏のサンプルコードを参考に一部を書き換えて走らせてみます。

完成図は以下のように認識した顔の周りに赤枠とラベルが表示されます。

まずは動作させるために、opencvをインストールする必要があるため、以下のコマンドを入力します。

pip install opencv-python

以下のプログラムを用意します。

from cProfile import label
from re import I
from tkinter import image_names
import face_recognition
import cv2
import numpy as np
import csv

video_capture = cv2.VideoCapture(0)

# 空の配列を定義しないとappendで要素を追加できない
labels = []
filenames =[]
images = []
encodings = []
known_face_encodings = []
known_face_names = []


# 画像リスト(csvファイルを読み込み
with open('list.csv',encoding="utf-8") as f:
    header = next(csv.reader(f))         # ヘッダーをスキップして2行目から読み込む
    reader = csv.reader(f)
    for row in reader:
        labels.append(row[0])            # 1列目のラベルデータをlabelsリストに格納する
        filenames.append(row[1])         # 2列目のデータをfilenameリストに格納する

data_num = len(filenames)    

for i in range(data_num):
    # 画像を読み込み、顔の特徴値を取得してリストに格納していく
    images.append(face_recognition.load_image_file("images/" + filenames[i]))
    encodings.append(face_recognition.face_encodings(images[i])[0])
    known_face_encodings.append(encodings[i])
    known_face_names.append(labels[i])

while True:
    # Webカメラの1フレームを取得、顔を検出し顔の特徴値を取得する
    _, frame = video_capture.read()
    #メモリ上の連続した配列(Cオーダー)を返す(変更)
    rgb_frame = np.ascontiguousarray(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)
        
        # 検出した人名をテキストファイルに書き込む
        with open("name.txt", "w", encoding='utf-8') as f:
            f.write(name)

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

video_capture.release()
cv2.destroyAllWindows()

uema氏のサンプルコードを走らせると以下のエラーが出ました。

Traceback (most recent call last):
~中略~

Invoked with: <_dlib_pybind11.face_recognition_model_v1 object at 0x0000018CC6CDDC70>, array([[[ 89, 111, 120],
        [ 97, 110, 124],
        [101, 106, 125],
        ...,
        [ 90,  92, 115],
        [ 94,  94, 119],
        [ 95,  95, 120]],

       [[ 70, 114, 127],
        [ 77, 113, 125],
        [ 84, 111, 123],
        ...,
        [ 86,  91, 101],
        [ 90,  92,  98],
        [ 95,  96, 103]],

       [[109, 110, 123],
        [ 97, 109, 122],
        [ 89, 111, 124],
        ...,
        [ 92,  93,  95],
        [ 95,  93,  91],
        [ 89,  87,  85]],

       ...,

       [[ 36,  32,  24],
        [ 39,  28,  24],
        [ 38,  19,  19],
        ...,
        [ 25,  20,  19],
        [ 27,  18,  18],
        [ 25,  16,  15]],

       [[ 49,  24,  21],
        [ 44,  22,  20],
        [ 35,  17,  17],
        ...,
        [ 27,  19,  18],
        [ 30,  18,  19],
        [ 31,  20,  20]],

       [[ 28,  19,  19],
        [ 34,  17,  18],
        [ 42,  17,  18],
        ...,
        [ 30,  20,  18],
        [ 33,  17,  19],
        [ 36,  20,  21]]], dtype=uint8), <_dlib_pybind11.full_object_detection object at 0x0000018CAFB077F0>, 1

そのため、該当部分を書き換えています。

# 変更前
rgb_frame = frame[:, :, ::-1]

# 変更後 メモリ上の連続した配列(Cオーダー)を返す
rgb_frame = np.ascontiguousarray(frame[:, :, ::-1])

プログラム実行の前に、.pyファイルのある階層に”images”フォルダを作成し、その中に”CEO.jpg”、”cowboy.jpg”、”niceguy.jpg”、”nicesmile.jpg”の画像ファイルを置きます。

私は以下のような画像を用意しました。お好みで好きな画像とファイル名に置き換えてください。

また、csvファイルのA列にラベル名、B列にファイル名を追加して、そのcsvファイルを読み込むことで、後からラベリングしたい人を追加できるようなプログラムにしています。

簡単なファイルですが一応貼っておきます。このファイルを走らせる.pyファイルと同じディレクトリに配置してください。

このファイルを走らせる.pyファイルと同じディレクトリに配置してください。

イメージとしては以下のようになります。

↓TOP階層

↓imagesフォルダ

コマンドプロンプトでディレクトリを上記のフォルダに移動させた後、以下のコマンドでプログラムを実行します。

python f_recog_rt.py

実行できました。

今回、同じ画像を使ってしまっているので、顔認識の精度の検証は行えていませんが、同じ顔をラベリングすることができました。

まとめ

face-recognitionを用いることで、Python初心者、顔認識初心者の私でも、顔認識を行うプログラムの実装することができました!

使えるものは使って、多大な勉強時間をかけなくても、面白いものをどんどん作っていきたいですね!

以上、”face-recognition”の紹介でした!

興味があれば試してみてください。

Pythonを使ってディープラーニングを作ってみたいという方は、以下の本で勉強を取り組んでみる始めることがおすすめです!

私はハードウェアエンジニアで、C言語の基礎くらいしか知りませんでしたが、pythonの基礎から載っていて何もわからない状態からディープラーニング実装までたどり着けました!

コメント

タイトルとURLをコピーしました