トラブルシューティング

多くの場合、「Windows 10 における動作環境作成とファイルの説明」あるいは「Ubuntu 18.04.4 における動作環境作成とファイルの説明」に沿って環境設定をしたのに Face01 が起動しない場合があります。こんな時は「環境設定をしたはずなのに後から調べたら出来ていなかった」という場合や「一度目は起動したけれど二度目からは起動しなくなった」等の症例があります。

ここではひとつづつ起こりうる症例と対策をご説明します。

また併せて「よくあるご質問」もご参照ください。

Face01 が起動しない

インストールされているモジュールを確認する

Windows 10 における動作環境作成とファイルの説明」に沿って環境設定をしたのに Face01 が起動しない場合、インストールされているモジュールを確認します。下図は対話型でモジュールがインポートできるかひとつづつ確認しています。

対話型でモジュールがインポートできるかひとつづつ確認する
対話型でモジュールがインポートできるかひとつづつ確認する

py.exe について調べる

コマンドプロンプトで >py と打った時に Python のバージョンがいくつになっているか調べます。3.6 以上になっていることを確認してください。

もし 2.x の場合は下図のように >py -3 と打ちこんで Python 3.6 以上になっているか確認してください。

パスの確認をする

CMake や Python のパスが通っているか確認してください。システムのプロパティ→詳細設定→環境変数を選択します。

システム環境変数→Path を選択して下図のようになっていることを確認します。

Ubuntu の場合

環境変数の表示には printenv コマンドをお使いください。

terms@terms-Desk:~$ printenv
CLUTTER_IM_MODULE=xim
LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64
PATH=/usr/local/cuda-10.2/bin:/home/terms/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
(略)

Python 自体のディレクトリは以下のようにして確かめます。

terms@terms-Desk:~$ which python3
/usr/bin/python3

システムの Python を使用しない、ホームディレクトリの任意の場所に Python をインストールしたなどの場合は以下のように export した後、再読込してください。

$ export PATH="/your/original/path/:$PATH"
$ source /home/your/.bashrc

Python が正しく起動するか確認する

作業ドライブにて以下のコードを「test.py」として保存します。

# coding:utf-8
print('Hello world')

コマンドプロンプトでこのディレクトリに移動し、以下のように打ち込みます。

Ubuntu の場合は端末に以下のように打ち込みます。

terms@terms-Desk:~$ python3
Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

ライブラリの確認を行う

必要なライブラリが import 出来るか確認します。 import できない場合は pip3 等でインストールしてください。ただし openCV はソースあるいはパッケージ管理システムから、Dlib はソースからインストールを行ってください。

terms@terms-Desk:~$ python3
Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> import PIL
>>> import dlib
>>> import face_recognition
>>> 

import の際は openCV なら cv2 、pillow なら PIL と打ち込んでください。例えば
>>> import pillow
と打ち込んでもエラーになりますので気をつけてください。

Dlib が CUDA 対応か確認する

terms@terms-Desk:~$ python3
Python 3.6.9 (default, Jul 17 2020, 12:50:27) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> import PIL
>>> import dlib
>>> import face_recognition
>>> dlib.DLIB_USE_CUDA
True
>>> 

True と返ってくれば CUDA を使用できます。

npKnown.txt があれば破棄する

前は起動したのに今度は起動しない…という場合があります。
「pictures_of_people_i_know」フォルダの中を改変した時は npKnown.txt を作り直すために一旦破棄しなければなりませんがこれを忘れている可能性があります。ですので既に npKnown.txt が有る場合は破棄してから Face01 を起動してください。

npKnown.txt

Face01 が起動してからのトラブルシューティング

「pictures_of_people_i_know」フォルダの中の顔画像を認識しない

load_priset_image() 関数(登録顔画像の登録処理)においては上図のようにマスクをはめている場合には、Face01 を呼び出す引数として「マスク用」を考慮しなければならない場合があります。通常、マスクの有りなしに関わらず mode は ‘hog’ 、 model は ‘large’ ですが、これで顔探索が難しい場合、 mode を ‘cnn’ にしたり、model を ‘small’ にしたり試行錯誤します。
( ただし Face01_Imager 1.1.3 以降では煩雑な引数処理を内部で自動的に切り替える仕様変更がなされました。これによって速度・正確性の向上を達成すると同時に引数を試行錯誤する手間がなくなりました。)

Face01_Graphics 使用での mode に関しては「各検出器の精度はどのくらい?」をご覧頂きそれぞれの精度の違いを確認してください。model に ‘small’ を指定したい場合は「マスクをつけた顔の検出・解析」をご覧ください。

例として Face01_Imager では以下のような引数指定のスクリプトになります。
( Face01_Imager 1.1.5 の場合 )

サンプルスクリプトの内容の説明については「マスクを考慮した場合には」をご参照ください。

# coding: utf-8

print('Start test_script')


import face01_imager_115 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=5,     # 処理速度優先
	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
		)

「pictures_of_people_i_know」フォルダを読み込む速度が遅い

登録顔画像を「pictures_of_people_i_know」フォルダから読み込む時には

  • 200×200 ピクセルの顔画像を
  • 解像度の良い状態で

読み込ませることが大事です。
例えば下の図は NG な例です。

登録顔画像として NG な例
登録顔画像として NG な例

傾いている顔を修正し、顔だけの 200×200 ピクセルにしたものが下の写真です。

登録顔画像として正しい例
登録顔画像として正しい例

顔に対して背景が大きいと人間には顔に見えなくても機械からは顔に見える場合があります。この場合複数顔が検出されてしまい顔登録が出来ません。
また大きな写真から小さな顔を探索するのには時間がかかります。何十人も登録する場合、顔の登録に大変な時間がかかります。
そして顔が傾いている場合は修正してください。傾いたままだと精度が落ちる可能性があります。

多くの写真から顔だけをクロップする場合、 FaceCrop を使用すると簡単です。

処理速度について

CPU だけに処理を行わせたい場合、処理速度が相対的に遅くなります。 Face01_Imager 1.1.3 以降では通常正確性と速度に優れた HOG にて処理を行い、HOG 形式で顔探索できない場合にのみ、内部で自動的に CNN 方式へと切り替えます。このように NVIDIA 製のグラフィックボードが調達できず CUDA 処理が出来ないシーンでも速度に与える影響を最小化する工夫が施してあります。

Face01_Imager の場合

load_priset_image() 関数 ( 登録顔画像の処理 ) では上述のようにマスクを考慮する場合でも通常は mode=’hog’ 、model=’large’です。これはface_attestation() 関数の場合も同様です。

上のサンプルスクリプトをご参照いただきたいのですが、顔認証部分の処理「face_attestation() 関数」を抜粋したのが下になります。

	xs = f.face_attestation( 
		check_images, 
		known_face_encodings, 
		known_face_names, 
		tolerance=0.5, 
		jitters=0,
		upsampling=0,
		mode='hog',      # CPU のみの処理の場合は hog を指定する
		model='large'
	)

速度に直結する引数は

  • jitters=0
    顔画像ファイルからランダムな顔を作り出し精度を向上させるもの
  • upsampling=0
    顔探索の領域指定。0 は 80×80 ピクセル以上の顔を探索する
  • mode=‘hog’
    CPU 処理に向いている顔認識モード
  • model=‘large’
    68-landmark model(※ ライセンスの関係で large を指定しても 5-point landmark model を使用します)
  • ( model=‘small’ )
    少しでも処理速度を上げたい場合、顔の上部部分のみで顔認証処理を行う 5-point landmark model を用いるための small 。
GPU ありで処理する場合

もし GPU カードをつけても良い場合は下のような最安値(税込3026円)のもので構いません。これでも CPU のみの処理速度と雲泥の差が出ます。

あくまでも Face01_Imager が処理速度優先のサーバで使うことを意識した前提になっているのでこの程度のカードでも十分です。
このカードを実際挿して処理速度を検証します。
先の Windows 10 で検証したのと同じコードを使い、どれくらいの時間がかかるか測定します。

動作環境
Ubuntu 18.04.4 64bit
CPU    AMD Ryzen5 1400
memory  16GB
GPU NVIDIA GT 710

標準出力に出力された顔認証速度の処理結果
標準出力に出力された顔認証速度の処理結果
137件の処理の場合の平均値など
265件の処理の場合の平均値など

265 件処理させてその平均値などを測定した結果が上のスプレッドシート図になります。
一枚の画像処理が平均 0.08 秒だと分かりました。3000 円ちょっとで買える GPU カードを取り付けられるのならば検討してみてください。

GPU カードがもしさせるとしたら dlib と face-recognition は CUDA に対応するよう CUDA オプションをつけて再インストールしてください。

Face01_Graphics の場合

Face01 は Face01_Imager よりも多くの計算資源を使います。Face01_Imager が計算資源の乏しいサーバで使うことを前提としているのに対して Face01_Graphihcs はより計算資源を使うことの出来るスタンドアロンで使用する前提だからです。

このようなことから Face01_Graphics で「処理速度が遅い」と感じる場合には Face01_Imager で行った引数の指定と同時にハードウェアも考慮しなくてはいけません。

マスクをつけた方々を顔登録・顔認証する現場の場合、基本的には

  • load_priset_image() 関数の引数(抜粋)は
    jitters=10,
    upsampling=0,
    mode=’cnn’,
    model=’large’
  • face_attestation() 関数の引数(抜粋)は
    jitters=0,
    upsampling=0,
    mode=’cnn’, # 速度が出る場合は ‘cnn’ と指定する
    model=’large’,
    frame_skip=10, # 手動ドロップフレーム。大きいほどカクカクする。
    movie=’usb’, # Web カメラを使う場合は ‘usb’ 、テスト用は ‘test.mp4’
    rectangle=’true’,
    show_video=’true’

サンプルスクリプト全体のコードは以下になります。

# 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=10, 
	upsampling=0, 
	mode='cnn', 
	model='large'
)


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

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]
		}
	})
	

サンプルスクリプトを動作させる前に npKnown.txt が存在する場合は一度破棄してからにしてください。

mode=’hog’ と mode=’cnn’ の「速度」「追従性」比較

サンプルスクリプトの face_attestation() 関数の引数「mode」にて、

  • mode=’hog’
  • mode=’cnn’

の実行速度と追従性の比較を検証した動画を紹介します。

mode=’hog’ と mode=’cnn’ の「速度」「追従性」比較

実行環境は以下になります。

検証環境:  
Python 3.6.9,
Ubuntu 18.04.3 LTS, 
Linux 4.15.0-66-generic, 
AMD Ryzen 5 1400,
MemTotal: 16421236 kB,
GeForce GT 710

mode=’hog’ では処理速度が早すぎて早送りのような状態になっています。これは face_attestation() 関数の引数 frame_skip=10 としているからであり、この様な場合は frame_skip=1 として良いと思います。

検証動画でおわかりの通り、

  • mode=’hog’ は処理速度が速くマスクの方への追従性が低い
  • mode=’cnn’ は処理速度は遅いがマスクの方への追従性が高い

ということがお分かりになるかと思います。

必要となるビデオカード

もし mode=’cnn’ であっても frame_skip を最低限にしたい…、つまりもっと滑らかな表示にしたい場合は今回使ったような 3000 円で買えるようなローエンドの GPU カードではなくミドルクラスのものに差し替えたほうが良いです。

たしか Dlib のサンプルコードの中に TitanX が候補に挙げられていましたので、上記くらいのグラフィックボードであれば大丈夫と思います。mode=’cnn’ を維持しつつリアルタイムでグラフィック処理が出来るでしょう。

Face01_Graphics が入力動画を認識しない

環境設定をする際、 openCV をインストールしますが pip でインストールした場合 Video I/O が有効になっていない場合があります。
これを確認するためには以下の様にします。

$ python3 -c ‘import cv2; print(cv2.getBuildInformation())’

この結果、下のようになっていたら動画入力できない状態です。ですのでソースからビルドするかパッケージ管理システムでインストールする必要があります。パッケージ管理システムの場合、openCV は python3-opencv です。

 Video I/O:
    DC1394:                      NO
    FFMPEG:                      NO
      avcodec:                   NO
      avformat:                  NO
      avutil:                    NO
      swscale:                   NO
      avresample:                NO
    GStreamer:                   NO
    v4l/v4l2:                    YES (linux/videodev2.h)

同一人物なのに face distance 値が大きい

予め同一人物と分かっているのに face distance 値が大きい場合、入力画像に使ったカメラと認証画像に使ったカメラが異なる事が多いです。

カメラが違うとついているレンズが違います。レンズには様々な収差と焦点距離があります。異なるカメラで撮影した人物が人間の目には同一人物に見えていても、プログラム側では異なる人物と判定されることがあります。下の GIF は焦点距離が異なる場合の顔の形状変化を端的に表現しています。

焦点距離の違いと顔の形状変化の様子

詳しくはレンズの歪曲収差と対応方法にまとめてありますのでご覧ください。

まとめ

今回は Windows 環境にてご説明させて頂きました。Face01 が起動しないところから速度に直接関係する引数指定をカバーしました。
Linux 環境や Face01_List については触れておりませんので後日追加するかも知れません。

Face01_Imager では特に引数の指定が重要であったため、1.1.3 以降では処理内部で自動的に速度と正確性を向上させる仕様変更がなされました
他方、Face01_Graphics そのものでは GUI ウィンドウに直接描画することから引数の指定だけではなく推奨するグラフィックカードもご紹介いたしました。

ハードウェア資源が限られている場合はきちんとした引数指定をする事が要となります。
ぜひ当ページを参考にして頂き、快適に Face01 シリーズをお使いください。

最後までお読み頂きありがとうございました。

Follow me!