Face01, Face01_imager の簡単な利用方法

アイキャッチ画像

Face01 の場合

今日は Face01 の簡単な利用方法について触れてみたいと思います。下のコードをご覧ください。

テストスクリプトのソースコード

# coding utf-8

print('Start test_script')


import face01_113 as f


kaoninshoDir, pictures_of_people_i_knowDir = f.home()


known_face_encodings, known_face_names = f.load_priset_image(
	kaoninshoDir,
	pictures_of_people_i_knowDir, 
	jitters=1, 
	upsampling=0, 
	mode='cnn', 
	model='small'
)


xs = f.face_attestation( 
	kaoninshoDir, 
	known_face_encodings, 
	known_face_names, 
	tolerance=0.5, 
	jitters=1,
	upsampling=0,
	mode='cnn', 
	model='small',
	frame_skip=1,
	movie='test.mp4',
	rectangle='true',
	show_video='true'
)

for x in xs:
	print ('name is ', x['name'])
	print ('date is ', x['date'])
	print ('location is ', x['location'])

上のコードのように Face01 を import してください。face_attestation() 関数の戻り値を for 文で回して name, date, location の各 key で値を得ます。

テストスクリプトの実行結果

実行結果は以下のようになります。

name is  山川04
date is  2019,08,28,07,58,34
location is  (152L, 342L, 259L, 235L) 

name is  西野02
date is  2019,08,28,07,58,34
location is  (175L, 724L, 283L, 617L) 
terminal に表示される様子
terminal に表示される様子

次は標準出力を json 風にしてみます。サンプルスクリプトの一部分だけ抜粋しています。

for x in xs:
	(name, pict, date, img, location) = (x['name'], x['pict'], x['date'], x['img'], x['location'])
	# ~ print({(name,pict)})
	# json 方式の出力
	print({
		"name": name,
		"pict": pict,
		"date": date,
		"location": {
			"top": location[0],
			"right": location[1],
			"bottom": location[2],
			"left": location[3]
		}
	})
terminal に表示される様子
terminal に表示される様子

おわかりのように ‘img’ のみ出力していません。これは他プログラムから Face01 を呼び出した時に動画の 1 フレームずつを numpy 行列で出力することによって GUI を構築するためのものです。例えば簡単な例をあげると matplotlab で動画として出力したサンプルがありますので「Face01 1.1.3 の numpy.ndarray 出力から matplotlib で動画再生」をご覧ください。

face_attestation() 関数の引数として show_video=’true’ とすると下図のように openCV 由来の GUI が表示されます。このウィンドウを表示させてくない場合は show_video=’false’ とします。

男女お二人の顔認識の様子
男女お二人の顔認識の様子

非常に短いコードで極めて簡単に名前や時間が取得できることがお分かりになると思います。

各フォルダ、各ファイルの紹介

npKnown.txt

npKnown.txt は load_priset_image() 関数とその引数により1つの顔に対して 128 個の生み出される数字を羅列したファイルです。もしプログラムのテスト中に pictures_of_people_i_know フォルダのファイルを差し替えた時は npKnown.txt を削除してください。自動的に再作成されます。

npKnown.txt
npKnown.txt の中身
npKnown.txt の中身

output フォルダ

顔認証処理が行われると顔の座標からその部分のみを切り出し顔ファイルとしてこのフォルダに保存されます。

output フォルダ
output フォルダ

ファイル名は「登録者名」と「日付時刻」で構成されます。

pictures_of_people_i_know フォルダ

登録者として顔画像とファイル名に登録者名をつけます。同一人物の違うファイルにはアルファベットをふっています。

pictures_of_people_i_know フォルダの中身
pictures_of_people_i_know フォルダの中身

noFace フォルダ

load_priset_image() 関数にて登録者顔ファイルに顔が含まれていない場合にこのフォルダに移動されます。
ただし前髪が目を覆うほど長い場合やマスクをはめている時、関数中の 引数を

mode='cnn',
model='small',

にしないと顔が認識されず noFace フォルダに移されてしまうこともあります。この場合は標準出力に Error ナニナニと表示されます。ただし model=’cnn’ は計算コストを使うため model=’hog’ を使う場合もあります。’hog’ の時に noFace フォルダに移動されない場合は ‘hog’ の方が計算コストが低いので現場では引数で調節することになります。

face01_imager の場合

face01_imager とは

サーバで複数の端末からの顔認証リクエストを効率良くさばけるように設計された face01 シリーズの一つです。
サーバに適した Face01 の開発」に紹介記事があるのでそちらも参照してください。

テストスクリプトのソースコード

# coding: utf-8

print('Start test_script')


import face01_imager_111 as f


kaoninshoDir, pictures_of_people_i_knowDir, check_images = f.home()


known_face_encodings, known_face_names = f.load_priset_image(
	kaoninshoDir,
	pictures_of_people_i_knowDir, 
	jitters=10, 
	upsampling=0, 
	mode='cnn', 
	model='small'
)


while(1):
	xs = f.face_attestation( 
		check_images, 
		known_face_encodings, 
		known_face_names, 
		tolerance=0.5, 
		jitters=0,
		upsampling=0,
		mode='cnn', 
		model='small'
	)

	for x in xs:
		(name, date) = (x['name'], x['date'])
		print(
			'name', name,
			'date', date
		)

テストスクリプトの実行結果

name 伊藤万理華d date 2020,07,06,09,08,22,160814
name 伊藤万理華d date 2020,07,06,09,08,22,166528
name 伊藤万理華d date 2020,07,06,09,08,22,172739
name オダギリジョーa date 2020,07,06,09,08,22,438277
name 永尾まりやd date 2020,07,06,09,08,22,651025
name 有村架純 date 2020,07,06,09,08,22,864447
Error: check_images フォルダ内の 76.jpg に顔が検出されませんでした。 noFace フォルダに移動します。
name キアヌリーブスb date 2020,07,06,09,08,23,261608
Error: check_images フォルダ内の 000000001.jpg は横幅 89 ピクセルです。小さすぎるので noFace フォルダに移動しました。
Error: check_images フォルダ内の A60.jpg に顔が検出されませんでした。 noFace フォルダに移動します。
name 石田ゆり子 date 2020,07,06,09,08,23,726217
name 柳楽優弥 date 2020,07,06,09,08,23,960179
name 柳楽優弥 date 2020,07,06,09,08,23,966030
name 波瑠 date 2020,07,06,09,08,23,972707
name 小池知事h date 2020,07,06,09,08,24,145457
name 小池知事h date 2020,07,06,09,08,24,150512
name 加藤厚労大臣c date 2020,07,06,09,08,24,155862
name 加藤厚労大臣e date 2020,07,06,09,08,24,485280
name 加藤厚労大臣c date 2020,07,06,09,08,24,779958
name 岡田健史 date 2020,07,06,09,08,24,993760

写真内に顔が含まれていないもの、写真サイズがあまりに小さいものは Error として noFace フォルダに移動しています。

サーバからの画像を受け付ける check_images フォルダ

check_images フォルダ
check_images フォルダ

check_images フォルダには各端末から次々と画像リクエストが来ます。この画像の中に予め登録しておいた顔画像がある場合、顔画像だけクロップして保存、また標準出力へ登録者名と時刻を表示し続けます。

処理された画像が移動される recognated フォルダ

処理された画像が移動される recognated フォルダ
処理された画像が移動される recognated フォルダ

顔認証処理された画像は次々と recognated フォルダへ移動されます。

登録者の顔画像を置いておく pictures_of_people_i_know フォルダ

顔画像登録者はファイル名を登録者名として pictures_of_people_i_know フォルダに置いておきます。

登録者の顔画像を置いておく pictures_of_people_i_know フォルダ
登録者の顔画像を置いておく pictures_of_people_i_know フォルダ

エンコードされた 128 次元数値データの npKnown.txt ファイル

登録者の顔画像は 128 次元数値データとしてエンコードされ、npKnown.txt ファイルに保存されます。

npKnown.txt ファイル
npKnown.txt ファイル

顔認証された顔データを保存する output フォルダ

顔認証処理により check_images フォルダ内の各画像から顔部分を切り出し、ファイル名に登録者名と時刻がセットされます。
登録者でなかった場合、ファイル名は「Unknown」となります。

顔認証された顔データを保存する output フォルダ
顔認証された顔データを保存する output フォルダ

標準出力画面に出力される顔認証結果のデータ

face01_imager の処理によって出力された顔認証データを標準出力する端末画面。
標準出力されることによって他のアプリケーションとの親和性を生み出します。前述した標準出力とは違う形式で出力してみました。

顔認証処理により標準出力画面に表示される顔データ
顔認証処理により標準出力画面に表示される顔データ

実際の動作画面

実際にどのように動いているのかをデスクトップキャプチャしました。
check_images フォルダの画像がどんどん処理されて減っていき、recognated フォルダへ移っていきます。また output フォルダにはクロップされた顔画像が登録者名をファイル名として続々と保存されていきます。
真ん中の端末画面にはエンコード中のファイル名や、顔認証処理された結果の登録者名が表示されていきます。

また、check_images フォルダがカラになった時、face01_imager は check_images フォルダに画像が来るのを待ち続けます。
ですので動画では一度処理された recognated フォルダに入っている画像を再び check_images フォルダに手動で投げ込んでみています。すると再び顔認証処理が行われる様子が見て取れると思います。

まとめ

以上です。
Face01 シリーズにはこれら以外に「face01_usb_windows_1.0」(Linux 版もあり)もあります。
こちらは USB カメラから入力された動画像から顔認証処理を行う face01_windows_1.0 です。
新規に顔画像登録する方法」で少し触れていますのでぜひご参照ください。

Follow me!