顔認証で勤怠管理を行う

顔認証システムで本人管理

というと2020年東京五輪ではNECの作った
高精度システムが使われることで有名ですね。

しかして顔認証システムも
誤差率を気にしなければ作るのは難しいものではありません。

特に社内で使うシステムなら誤差修正も用意なので、
簡易的に実装して試験運用するのも手です。

本日は簡易的な顔認証勤怠管理システムを実装してみましょう。

環境準備

先日の顔認証デモに関する記事でも書いていますが
最近はface_recognitionというpythonの顔認証ツール
Githubで公開され、MITライセンスで使えるので利用も自由と大変便利ですね。

実行環境として
・python
・dlib
・face_recognition
の3つを起点にphpで動かしていきます。

Pythonの編集

今回はリアルタイム検出を使うのでこちらのサンプルコードを使用します。
が、これは毎度特徴量を検出し使用するので、このままでは起動に時間がかかります。

そこで写真の検出処理とビデオの検出処理を切り離し、外部から特徴量を読み取り使用します。
が、簡易実装故にDB接続も行いたくないので、今回はjsonで全て処理します。

顔特徴量検出部分

import sys
import json

import face_recognition
import cv2
import numpy

use_dir = sys.argv[1]
json_dir = sys.argv[2]
js_path = sys.argv[3]
save_json = sys.argv[4]
user_name = sys.argv[5]

with open(json_dir+js_path) as f:
	jsons = json.loads(f.read())

encode = []

for image in jsons:
	enc_image = face_recognition.load_image_file(use_dir+image)
	face_encoding = face_recognition.face_encodings(enc_image)[0]
	encode.append([user_name, face_encoding.tolist()])

with open(json_dir+save_json, 'w') as fw:
	json.dump(encode, fw, indent=4)

顔特徴量検出部分のpythonコードです。
写真ファイル名が書かれたjsonファイルをPHPで出力し、
pythonで読み込んでから一枚ずつ座標検出し
結果をjsonで出力します。

注意するのはtolist()。
face_recognitionは結果をnumpy配列で返しますが
json.dumpはnumpy配列を格納できません。
一度numpy配列をpythonリスト化するtolist()が必要になります。

因みに今回は最終的に一度に3枚しか写真を渡してないので
1つ目のjsonファイルは絶対に必要という訳ではなくなりました。
ファイルを10,20と送る場合にはあった方が良いでしょう。

あとコードがだらだらしてるのは簡易実装だからですね。
簡易実装、便利な言葉です。

PHP側補足

顔認証で勤怠管理を行う

完成後の画面になりますが、今回は3枚の写真から1人の検証用jsonを作成します。
(下のinput textが登録する人物の名前)

※今回もぱくたそ様の写真を使わせて頂いております。
※本来は顔の左右と正面の写真を使うのが理想的です。

複数人の検証に対応するため、2人目のjson作成時に1人目のjsonファイルと結合する処理を入れてあります。
角度違いの3枚の画像を1人目と同じ名前で登録すれば1人目の精度を上げることもできます。

ビデオ検出側

import face_recognition
import cv2
import json

use_dir = './json/'
js_path = '03_detect.json'

with open(use_dir+js_path) as f:
	jsons = json.loads(f.read())

known_face_encodings = []
known_face_names = []

for name, encode in jsons:
	known_face_encodings.append(encode)
	known_face_names.append(name)

#=以降ほぼサンプル通り========================
# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
~

ビデオ検出側はサンプルと殆ど同じですが、最初にjsonファイルを読み込む処理を入れてあります。
use_dirとjs_pathは自分の環境に合わせたお好きな値でご利用ください。

因みにface_recognitionに渡す顔の検出値はリストのままで良かったりします。何故?

またサンプルのままだとビデオが回り続けるので終了処理を入れます。

if True in matches:
	first_match_index = matches.index(True)
	name = known_face_names[first_match_index]
	print(name)
	video_capture.release()
	cv2.destroyAllWindows()

あとは出力されたprint(name)-登録者名-をphpで拾って出力するだけです。

結果ページ

顔認証で勤怠管理を行う

三枚の写真アップロード後、カメラ起動ボタンでPCに接続されたカメラが起動します。
※今回PC画面に表示した写真を認識させています。

顔認証で勤怠管理を行う

そして認証すれば登録者名が返ります。
返った値をタイムカードの打刻等に使用すれば勤怠管理システムの完成です。
簡単ですね。

まとめ

PHP側のコードは諸々の事情によりご容赦ください。
処理としてはアップ画像の名前をjson出力し、
pythonが出力したエンコード結果jsonを、
1人目がいれば結合、いなければそのままjson出力し、
カメラ起動用のボタンと認証からの出力処理を入れているだけです。

jsonを使ったビデオキャプチャ機能は単体で動きますので、

[
	["登録者名1",
		[登録者名1のエンコード結果]
	],
	["登録者名2",
		[登録者名2のエンコード結果]
	]
]

の形式のjsonファイルがあれば動作します。
テストなどしたい場合はこちらの形式でお試しください。

さて書いてきたとおり、顔認証を使った簡易勤怠管理システムは容易に作成できます。
精度を上げる場合はもっと複雑な処理を挟みますが基礎は完成です。

顔認証の導入も敷居はどんどん下がってきていますね。
しかもface_recognitionを使えばUSBカメラだけで導入できる
(ついでに今回のシステムはjsonだけで動作するのでDBも不要)ので
安価、かつお手軽に導入できます。
顔認証での本人確認は便利ですね。

最新ブログ一覧