Face01 1.1.4 の呼び出し方について解説します

この解説ページは「Face01 1.1.2 の呼び出し方について解説します」をベースに、バージョン 1.1.4 に対応するように書き換えました。

Face01 におけるバージョン 1.1.4 について引数の説明をいたします。

# coding utf-8

print('Start test_script')


import face01_112 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=10, 
	upsampling=0, 
	mode='cnn', 
	model='small'
)


xs = f.face_attestation( 
	kaoninshoDir,
	known_face_encodings, 
	known_face_names, 
	tolerance=0.5, 
	jitters=0,
	upsampling=0,
	mode='hog', 
	model='small',
	frame_skip=9,
	movie='test.mp4', # web カメラを用いる場合は movie='usb'
	rectangle='true'
	show_video='true',
	frequency_crop_image=20
)

for x in xs:
	(name, pict, date, img) = (x['name'], x['pict'], x['date'], x['img'])
	print({(name,pict)})
	

'''
変数について
jitters			ゆらぎ値。ランダムにスケールアップや色の修正をして平均値を返す。デフォルト値 0
upsampling		サンプリング指定値。0 の時 80x80 ピクセルで顔探索をする。1 では 40x40 ピクセル。
mode			CNN, HOG 両形式を指定する。
model			small -> 5-points method, large -> 68-points method
tolerance		閾値。
frame_skip		フレームドロップの割合。入力が 30fps の場合 frame_skip=2 では 15fps となる
movie			動画入力元を test.mp4 と USB カメラの 2 種類から選ぶ
rectangle		顔周囲に枠を描画するか否か。true:描画する。false:描画しない
show_video		openCV 由来の GUI による動画表示の有無
frequency_crop_image	フレームをいくつ飛ばして output するか調節する
'''

今までの

  • Face01_HOG
  • Face01_CNN
  • Face01_USB_HOG
  • Face01_USB_CNN

は全て統合され単一の Face01 となります。
すなわち HOG 形式か CNN 形式か、あるいは動画入力元が Web カメラか test.mp4 からかを引数から選べるようになりました。

コメントにもあるように、それぞれの関数に与える引数を自由に変えられるようになりました。これによって呼び出す側に自由度を与えますが、反対に顔認証のアルゴリズムや各々の変数の働きが分かっていないと期待しない動作になってしまいます。
ですので内部があまりよく理解できていない場合は「変数を指定しない」というのも一つの手です。デフォルトの動作として変数を与えなくても内部でよろしくやってくれるようになっています。ただしマスクをしたまま顔認証する場合はきちんと働きを知っておく必要があります。
参考文献として「顔認証、マスクをつけたらどうなるの?」を最初にお読みになってください。
では一つづつ変数を確認していきましょう。

各変数の働き

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 の値を大きくするほどランダムな変換の平均値をとるようになります。
しかしながら大きな値をとることによって入力画像が不確かなものになっていくこと、処理時間が長くなることが懸念されます。
通常は 5 〜 10 あたりが良いように感じます。

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 で良好な結果を出します。ですので upsampling=0 にするのが良いでしょう。

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 参照
実際には RTX 2070 SUPER などが妥当だと思います)
GPU が使えない状況下にあっては HOG 形式を使うほうが現実的でしょう。
マスクをした顔の場合は CNN 形式が良好な結果を出力します。

model

small: 5-points method
large: 68-points method
となります。
マスクをはめたまま顔認証するときには small を選んでください。顔の半分が布で覆われているからです。

tolerance

0.6 を基準としてトレーニングしてあります。これより大きければ他人と判断されます。
アジア人の場合、0.45〜0.55 くらいに設定しましょう。

frame_skip

フレームドロップの割合です。入力が 30fps の場合 frame_skip=2 では 15fps となります。処理するコンピュータの性能によってさばけるフレーム数は異なります。また mode に cnn を選んだ時などマシンに負荷がかかって処理が遅くなってしまう場合この引数を使ってフレームを手動でドロップします。
一般に mode では CNN 形式よりも HOG 形式のほうが負荷が軽く、model では large より small の方が負荷が軽くなります。

movie

動画入力元を test.mp4 と USB カメラの 2 種類から選ぶ事が出来ます。test.mp4 は 同一ディレクトリに配置してください。

  • movie=’test.mp4′
  • movie=’usb’

のいずれかを選びます。デフォルト値は ‘test.mp4’ 。

rectangle

顔周囲に枠を描画するかどうかを指定します。

  • rectangle=’true’
    外枠を描画する
  • rectangle=’false’
    外枠を描画しない
  • デフォルト値
    true
rectangle='true' 外枠描画
rectangle=’true’ 外枠描画
rectangle='false' 外枠を描画しない
rectangle=’false’ 外枠を描画しない

show_video

openCV 由来の GUI 表示をするかしないかを選べます。
独自に GUI を作りその中に顔認証済み動画を埋め込みたいときなどに使います。下図では簡単な例として matplotlab を用いて関数の返り値から GUI ウィンドウを開いています。

frequency_crop_image

これまで(バージョン 1.1.3 )は 1 フレームごとに output として顔をクロップした顔画像ファイルを出力していましたが、これだと io 速度が律速ポイントとなってしまいます。
バージョン 1.1.4 からは n 枚のフレームごとに 1 つの顔画像ファイルを出力することが指定できます。これにより Face01 の速度を向上させることが出来ます。

mode と model の使い分け

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

load_priset_image() 関数

pictures_of_people_i_know ディレクトリに登録されている顔画像ファイルを 128D 顔識別子にエンコードする際に用いられます。
マスクをしている顔画像ファイルがある場合、
mode: cnn
model: small

とすると良いでしょう。
マスクを考慮に入れなければ
mode: hog
model: large
とすることで精度と速度が上がります。
無いとは思いたいですが pictures_of_people_i_know フォルダにぼやっとした顔を登録すると cnn 形式でないと読み込めない場合があります。

face_attestation() 関数

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

マスクを考慮に入れなければ
mode: hog
model: large
を指定してください。ただし mode の項で触れたとおり顔認識の精度の高い cnn を選択する場合は速度とトレードオフになることに注意してください。十分な性能の NVIDIA 製 GPU を搭載していれば速度的には問題になりません。
またチェックされる画像の照明の当たり具合や焦点ボケが発生している場合、cnn 形式でないと顔を認識できない場合があります。

デフォルト値

マスクをした状態を CPU のみで処理を行うこと前提の引数値になっています。

load_priset_image() 関数の場合

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

80×80 ピクセルでの顔探索、jitters ( ゆらぎ値 ) は 10 、HOG 形式、5-points method となっています。
pictures_of_people_i_know フォルダに登録する顔画像ファイルはマスクあり、200×200 ピクセル。
マスクをはめた顔を想定しています。

face_attestation() 関数の場合

xs = f.face_attestation( 
	kaoninshoDir, 
	known_face_encodings, 
	known_face_names, 
	tolerance=0.5, 
	jitters=0,
	upsampling=0,
	mode='hog', 
	model='small',
	frame_skip=3,
	movie='test.mp4',			# Web カメラからの入力は movie='usb'
	rectangle='true',
	show_video='true',
	frequency_crop_image=10
)

80×80 ピクセル以上の顔、jitters ( ゆらぎ値 ) は 0 、tolerance ( 許容値(閾値)) は 0.5 、HOG 形式、5-points method 、手動でのフレームドロップは 3 ( 元が 30fps の場合 10fps ) 、動画入力元は test.mp4 となっています。こちらは CPU のみで処理を前提としています。

マスクを考慮しない場合には

こちらも CPU のみで処理することを前提にしています。

load_priset_image() 関数の場合

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

mode を cnn 、 model を large 、upsampling を 0 ( 80×80 ピクセル ) にします。

face_attestation() 関数の場合

def face_attestation(
	kaoninshoDir, 
	known_face_encodings, 
	known_face_names, 
	jitters= 0, 
	tolerance=0.5, 
	mode='hog', 
	model='large', 
	upsampling=0, 
	frame_skip=3, 
	movie='test.mp4', 
	rectangle='true', 
	show_video='true', 
	frequency_crop_image=10
):

こちらも、mode を hog 、 model を large にします。また upsampling は 0 、フレームドロップを 3 にして 1/3 の負荷にしています。

GPU が使える場合には

NVIDIA 製の GPU が使える場合にはまず dlib と face-recognition を CUDA 仕様にしてください。
以下はマスクをはめた状態を想定しています。

load_priset_image() 関数の場合

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

face_attestation() 関数の場合

xs = f.face_attestation( 
	kaoninshoDir, 
	known_face_encodings, 
	known_face_names, 
	tolerance=0.5, 
	jitters=0,
	upsampling=0,
	mode='cnn', 
	model='small',
	frame_skip=1,
	movie='test.mp4',			# Web カメラからの入力は movie='usb'
	rectangle='true',
	show_video='true',
	frequency_crop_image=10
)

まとめ

上記リンク先も参照してください。

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

Follow me!