FACE01 IMAGER 1.1.4 の呼び出し方

こちらの記事は内容が古くなっており正確ではありません。
最新の記事をご参照下さい。

FACE01 IMAGERは 1.1.4 から更に便利な機能が追加され精度も向上しています。各メソッドの詳細な解説と具体的な数値のとり方をご説明いたします。

# coding: utf-8

print('Start test_script')


import face01_imager_114 as f
import time


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=2,     # 処理速度優先
	upsampling=0,  # 200x200 ピクセルの顔画像ファイルであることが前提
	mode='hog',    # hog で固定
	model='large'  # large で固定
)


while(1):
	xs = f.face_attestation( 
		check_images, 
		known_face_encodings, 
		known_face_names, 
		tolerance= 1.0,                 # 最初は tolerance を開放する ( 1.0 )
		jitters=0,
		upsampling=0,
		mode='hog',                     # hog で固定
		model='large',                  # large で固定
		display_face_distance = 'true'  # 閾値を求めるために true にする
	)


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

コメントにもあるように、それぞれの関数に与える引数を自由に変えられるようになりました。これによって呼び出す側に自由度を与えますが、反対に顔認証のアルゴリズムや各々の変数の働きが分かっていないと期待しない動作になってしまいます。
ですので内部があまりよく理解できていない場合は「変数を指定しない」というのも一つの手です。デフォルトの動作として変数を与えなくても内部でよろしくやってくれるようになっています。
バージョン 1.1.4 からは簡単に tolerance の値、つまり閾値(しきい値)を設定できるように工夫されています。
詳しくはこちらの動画をご覧ください。

簡単なしきい値 ( tolerance ) の求め方

参考文献として「顔認証、マスクをつけたらどうなるの?」を最初にお読みになってください。
では一つづつ変数を確認していきましょう。

各変数の働き

jitters

dlib を git clone した場所、私の場合なら $HOME/dlib/python_examples/ ディレクトリの face_jitter.py ファイルを参照してください。そこには以下のように記述してあります。
It takes an input image and disturbs the colors as well as applies random translations, rotations, and scaling.
「入力画像を受け取り、色を乱し、ランダムな移動、回転、スケーリングを適用します。」
jitters の値を大きくするほどランダムな変換の平均値をとるようになります。
しかしながら大きな値をとることによって入力画像が不確かなものになっていくこと、処理時間が長くなることが懸念されます。
通常は 0 ~ 2 あたりが良いように感じます。

upsampling

How many times to upsample the image looking for faces. Higher numbers find smaller faces.
「顔を探して画像をアップサンプリングする回数。 数値が大きいほど顔が小さくなります。」
具体的には upsampling が 0 の時 80×80 ピクセル、1 の時に 40×40 ピクセル、2 の時に 20×20 ピクセルの範囲で顔を探索します。処理時間とトレードオフになります。
下図の例では 80x80px で良好な結果を出します。

mode

CNN 形式または HOG 形式のどちらかを選びます。
CNN: Convolutional Neural Network
HOG: Histogram of Oriented Gradients
速度は HOG が速く CNN で同等の速度を出そうとすれば NVIDIA Titan X GPU が必要になります。
( $HOME/dlib/python_examples/dnn_mmod_face_detection_ex.cpp 参照)
ただし Face01_imager であれば元々の処理時間が少ないため、あえて CNN を選んでも良いと思います。マスクをした顔の場合は CNN 形式が良好な結果を出力します。

tolerance

0.6 を基準としてトレーニングしてあります。これより大きければ他人と判断されます。
アジア人の場合、0.45〜0.55 くらいに設定しましょう。
実際の現場ではカメラを動作させてみて閾値を決めることがほとんどですが、これは経験がある方向けです。もっと簡単にしきい値 ( tolerance ) を求める方法として先の動画に解説しましたのでご覧ください。

mode と model の使い分け

まず各関数がどのような働きをしているか簡単に説明します。

load_priset_image() 関数

pictures_of_people_i_know ディレクトリに登録されている顔画像ファイルを 128D 顔識別子にエンコードする際に用いられます。
マスクの有り無しも含めて通常は
mode: ‘hog’
model: ‘large’

pictures_of_people_i_know フォルダにぼやっとした顔やマスクをはめた顔を登録するした場合 HOG モードでは読み込めない事があり、この様なときはプログラム内部でその部分だけ CNN モードで顔探索処理を行います。

face_attestation() 関数

load_priset_image() 関数で 128D 顔識別子でエンコードされたデータと比較するためにここでも 128D エンコードを行います。
先と同じようにマスクの有り無しも含めて
mode: ‘hog’
model: ‘large’

を指定します。
処理対象の静止画に HOG モードでは顔を探索できないときのみ、内部で CNN モードに切り替えて顔探索処理を行います。

デフォルト値

load_priset_image() 関数の場合

kaoninshoDir,
pictures_of_people_i_knowDir,
upsampling=0, 
jitters=10, 
mode='hog', 
model='large'

80×80 ピクセルでの顔探索、jitters ( ゆらぎ値 ) は 10 、HOG モード、68-points landmark model となっています。
pictures_of_people_i_know フォルダに登録する顔画像ファイルは
マスク有り無し、200×200 ピクセル、CPU のみでの処理
を前提とした内容です。

face_attestation() 関数の場合

check_images, 
known_face_encodings, 
known_face_names, 
jitters=0, 
tolerance=0.5, 
mode='hog', 
model='large', 
upsampling=0,
display_face_distance='true'

80×80 ピクセル以上の顔、jitters ( ゆらぎ値 ) は 0 、tolerance ( しきい値 ) は 0.5 、HOG モード、68-points landmark model となっています。こちらもマスクの有り無しはどちらでも良い・速度を重視した CPU のみで十分処理速度がある設定となっています。

まとめ

今回の変更により、現場でマスクあり・なしの状況変化に柔軟に対応できるようにいたしました。
反面では変更できる変数や関数の働きを理解しないといけないものになっています。
今までは model や mode などごとに違うアプリケーションとしてご用意させていただいておりましたが、現場で柔軟に変えられたほうが良いだろう…という考えがありました。
もし疑問点・不明な点があればお問い合わせからご連絡いただけると幸いです。