トラブルシューティング

実行環境構築 Windows 10」あるいは「実行環境構築 Ubuntu18.04」に沿って環境設定をしたのに FACE01が起動しない、一度目は起動したけれど二度目からは起動しなくなった」。そんな時はこのページを読んでみて下さい。

「環境設定をしたはずなのに後から調べたら出来ていなかった」や「パスが通っていなかった」等の起こりうる症例と対策をご説明します。

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

サンプルアプリケーションのうちEXE版に関してはこちらのページで取り扱いません。大変お手数をおかけいたしますがメールにてご連絡下さいませ。

FACE01が起動しない

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

実行環境構築 Windows 10」に沿って環境設定をしたのにFACE01が起動しない場合、インストールされているモジュールを確認します。下図は対話型でモジュールがインポートできるかひとつづつ確認しています。

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

python.exeのバージョンを確認する

システムPythonを使わずPyenvによる仮想環境構築を推奨します。
以下の説明はシステムPythonのトラブルシューティングです。

コマンドプロンプトでPython のバージョンを確認します。Windows版とUbuntu版ではPythonのバージョンが異なります。

  • Windows
    • Python3.7.7
  • Ubuntu
    • Python3.6.9
# Windows
>python --version

# Ubuntu
$ python3 --version
Windows
Ubuntu

パスの確認をする

CMake や Python のパスが通っているか確認してください。

Windowsの場合

システムのプロパティ→詳細設定→環境変数を選択します。

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

Ubuntuの場合

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

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

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

$ which python3
/usr/bin/python3

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

$ export PATH="/任意のディレクトリ/:$PATH"
$ source /home/ユーザ名/.bashrc

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

Windows

>python
Python 3.7.7
>>>

Ubuntu

$ 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 出来るか確認します。 import できない場合は pip3 等でインストールしてください。(仮想環境をお使いの方はそれに準じて下さい)

## Ubuntu
$ 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
>>> 

openCVのインストール

openCV はパッケージ管理システムからインストールできます。

$ sudo apt install python3-opencv

あるいはpip3からインストールします。

$ pip3 install opencv-python
$ pip3 install opencv-python
Collecting opencv-python
  Downloading https://files.pythonhosted.org/packages/bb/08/9dbc183a3ac6baa95fabf749ddb531bd26256edfff5b6c2195eca26258e9/opencv-python-4.5.1.48.tar.gz (88.3MB)
    100% |████████████████████████████████| 88.3MB 17kB/s 
Collecting numpy>=1.13.3 (from opencv-python)
  Downloading https://files.pythonhosted.org/packages/45/b2/6c7545bb7a38754d63048c7696804a0d947328125d81bf12beaa692c3ae3/numpy-1.19.5-cp36-cp36m-manylinux1_x86_64.whl (13.4MB)
    100% |████████████████████████████████| 13.4MB 113kB/s 
Building wheels for collected packages: opencv-python
  Running setup.py bdist_wheel for opencv-python ...
Building wheels for collected packages: opencv-python
   Running setup.py bdist_wheel for opencv-python … done
   Stored in directory: /home/terms/.cache/pip/wheels/08/40/b7/fb2e8392888c91eb048b26ea0baa9aae808d056e3786204d0b
 Successfully built opencv-python
 Installing collected packages: numpy, opencv-python
 Successfully installed numpy-1.19.5 opencv-python-4.5.1.48

システムPython使用時、パッケージマネージャからのインストールとpipからのインストールはどちらかを排他的に選択して下さい。opencv-pythonなどは競合する場合があります。

openCV をGPU対応にするには

FACE01がGPU版openCVに対応しておりません。ソースコードを取り扱うときのみ以下の操作をして下さい。

openCVのGPU対応はソースからマニュアルで行います。公式ページを参照して下さい。

dlibのインストール

Dlibをソースからインストールする場合は以下のようにします。

$ python3 setup.py install

pip3でインストールする場合は以下のようにします。

$ pip3 install dlib
Collecting dlib
  Downloading https://files.pythonhosted.org/packages/11/93/ec41d6ef7e769977aa08e49441c52276da27859f12dcbf1c6deb96ce5e9f/dlib-19.22.0.tar.gz (7.4MB)
    100% |████████████████████████████████| 7.4MB 196kB/s 
Building wheels for collected packages: dlib
  Running setup.py bdist_wheel for dlib ... done
  Stored in directory: /home/terms/.cache/pip/wheels/bd/46/7c/deeb33803394006488f2378a9adeae08c65c9560f27a85fbce
Successfully built dlib
Installing collected packages: dlib
Successfully installed dlib-19.22.0
$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dlib
>>> dlib.DLIB_USE_CUDA
True
>>> 

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

OSのパッケージマネージャを使用できる場合にはパッケージマネージャの使用を強くお勧め致します。

Dlib が CUDA 対応か確認する
$ 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 dlib
>>> dlib.DLIB_USE_CUDA
True
>>> 

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

npKnown.txt があれば破棄する

FACE01 GRAPHICS 1.2.4からnpKnown.txtにかわりnpKnown.npzへ形式が変更されました。それに伴い(トラブルがない限り)npKnown.npzは削除する必要はありません

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

npKnown.txt

SETTING MANAGERでは下図の赤い四角で囲ったチェックボタンにチェックを入れることで自動的にnpKnown.txtが破棄・再構築されます。

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

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

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

FACE01 IMAGERでは以下のような引数指定のスクリプトになります。

# 変数設定 ==========================
## 説明(default値)
## 閾値(0.5)
tolerance=0.45
## ゆらぎ値(0)
jitters=0
## 登録顔画像のゆらぎ値(10)
priset_face_images_jitters=10
## 最小顔検出範囲(0)
upsampling=1
## 顔検出方式(cnn)
### ビデオカードがない場合はmode='hog'
mode='cnn'
# ===================================

from concurrent.futures import ProcessPoolExecutor
import FACE01IMAGER125 as fi

kaoninshoDir, priset_face_imagesDir, check_images = fi.home()

known_face_encodings, known_face_names = fi.load_priset_image.load_priset_image(
    kaoninshoDir,
    priset_face_imagesDir, 
    jitters=priset_face_images_jitters
)

# 並行処理
def multi(x):
    print(
        'name', name,
        'date', date,
        'face distance',distance,
        'original photo', original_photo
    )

while(1):
    xs = fi.face_attestation( 
        check_images, 
        known_face_encodings, 
        known_face_names, 
        tolerance=tolerance, 
        jitters=jitters,
        upsampling=upsampling,
        mode=mode
    )

    pool=ProcessPoolExecutor()
    for x in xs:
        name, date, distance, original_photo = x['name'], x['date'], x['face_distance'], x['original_photo']
        result=pool.submit(multi, x)

# 終了
print('終了します')

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

GPUに対応しているか確認する

以下のようにしてGPUに対応しているか確認をして下さい。

$ python3
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dlib
>>> dlib.DLIB_USE_CUDA
True
>>> 

Trueと返ってくればGPU対応になっています。FalseであればGPU導入をご参照ください。

登録顔画像ファイルについて確認する

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

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

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

登録顔画像として NG な例

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

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

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

処理速度について

FACE01シリーズをお使い頂くにあたりGPUカードがない場合はFACE01 IMAGERをお使い下さい。FACE01 GRAPHICSをお使いになる場合はNVIDIA GeForce GTX 1660 Ti相当以上を必要とします。

FACE01 IMAGERの場合

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

load_priset_image() 関数 ( 登録顔画像の処理 ) では上述のようにmode=’hog’ です。これはface_attestation() 関数の場合も同様です。

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

# 変数設定 ==========================
## 説明(default値)
## 閾値(0.5)
tolerance=0.45
## ゆらぎ値(0)
jitters=0
## 登録顔画像のゆらぎ値(10)
priset_face_images_jitters=10
## 最小顔検出範囲(0)
upsampling=1
## 顔検出方式(cnn)
### ビデオカードがない場合はmode='hog'
mode='cnn'
# ===================================

速度に直結する引数は

  • jitters=0
    顔画像ファイルからランダムな顔を作り出し精度を向上させるもの
  • upsampling=0
    顔探索の領域指定。0 は 80×80 ピクセル以上の顔を探索する
  • mode=‘hog’
    CPUのみの処理に向いている顔認識モード。マスクには対応していない
GPU ありで処理する場合

GPU カードをつけても良い場合は下のような最安値(税込3026円)のものだとしても CPU のみの処理速度と雲泥の差が出ます。(注意:使えるGPUカードはCUDA-Toolkitのバージョンに依存します。下にあげたGPUカードが使えない場合もあります)

このカードを実際挿して処理速度を検証します。
先の 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の性能が上がればそれだけ処理速度は速くなります。

GTX1660Tiの場合、hogよりもcnn指定の処理速度が速くなります。FACE01 IMAGERよりも重い処理を行うFACE01 GRAPHICSの場合でも平均処理速度は0.014秒ほどになります。

必要となるビデオカード

通常はミドルクラス以上に差し替えたほうが良い結果を得られます。

GPU カードがもしさせるとしたら dlib と face-recognition は CUDA に対応するよう CUDA オプションをつけて再インストールしてください。OSがパッケージマネージャを持つ場合、パッケージマネージャを使用することで自動的にGPU対応となります。

FACE01 GRAPHICSの場合

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

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

SETTING MANAGERを用いない場合

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

# 変数設定 ==========================
## 説明(default値)
## 閾値(0.5)
tolerance=0.45
## ゆらぎ値(0)
jitters=0
## 登録顔画像のゆらぎ値(10)
priset_face_images_jitters=10
## 最小顔検出範囲(0)
upsampling=1
## 顔検出方式(cnn)
### ビデオカードがない場合はmode='hog'
mode='cnn'
# ===================================

from concurrent.futures import ProcessPoolExecutor
import FACE01IMAGER125 as fi

kaoninshoDir, priset_face_imagesDir, check_images = fi.home()

known_face_encodings, known_face_names = fi.load_priset_image.load_priset_image(
    kaoninshoDir,
    priset_face_imagesDir, 
    jitters=priset_face_images_jitters
)

# 並行処理
def multi(x):
    print(
        'name', name,
        'date', date,
        'face distance',distance,
        'original photo', original_photo
    )

while(1):
    xs = fi.face_attestation( 
        check_images, 
        known_face_encodings, 
        known_face_names, 
        tolerance=tolerance, 
        jitters=jitters,
        upsampling=upsampling,
        mode=mode
    )

    pool=ProcessPoolExecutor()
    for x in xs:
        name, date, distance, original_photo = x['name'], x['date'], x['face_distance'], x['original_photo']
        result=pool.submit(multi, x)

# 終了
print('終了します')
# 変数設定 ==========================
## 説明(default値)
## 閾値(0.5)
tolerance=0.45
## ゆらぎ値(0)
jitters=0
## 登録顔画像のゆらぎ値(10)
priset_face_images_jitters=10
## 最小顔検出範囲(0)
upsampling=0
## 顔検出方式(cnn)
mode='cnn'
## フレームドロップ率(-1)
frame_skip=-1
## 入力映像(test.mp4)
movie='some_people.mp4'
## 顔枠表示シンプル(False)
rectangle=False
## 顔枠表示標準(True)
target_rectangle=True
## 簡易ウィンドウ表示(False)
show_video=False
## 顔画像保存割合(10)
frequency_crop_image=10
## 表示エリア(NONE)
set_area='NONE'
## 収差学習<未実装>(False, 1)
face_learning_bool=False
how_many_face_learning_images=1
## 映像データ標準出力(False)
output_frame_data_bool=False
## 映像データプロパティ表示(False)
print_property=False
## 単一処理時間表示(False)
calculate_time=True
## 映像データ大きさ
SET_WIDTH=500
# ===================================


import time
from concurrent.futures import ProcessPoolExecutor
import cv2
import PySimpleGUI as sg
import FACE01GRAPHICS125 as fg

kaoninshoDir, priset_face_imagesDir=fg.home()
    
known_face_encodings, known_face_names=fg.load_priset_image.load_priset_image(
    kaoninshoDir,
    priset_face_imagesDir, 
    jitters=priset_face_images_jitters, 
)

xs=fg.face_attestation(
    kaoninshoDir, 
    known_face_encodings, 
    known_face_names, 
    tolerance=tolerance, 
    jitters=jitters, 
    upsampling=upsampling,
    mode=mode, 
    model='small', 
    frame_skip=frame_skip, 
    movie=movie, 
    rectangle=rectangle, 
    target_rectangle=target_rectangle, 
    show_video=show_video,
    frequency_crop_image=frequency_crop_image, 
    set_area=set_area,
    face_learning_bool=face_learning_bool,
    how_many_face_learning_images=how_many_face_learning_images,
    output_frame_data=output_frame_data_bool,
    print_property=print_property,
    calculate_time=calculate_time,
    SET_WIDTH=SET_WIDTH
)

# window実装
layout=[
    [sg.Text('GUI実装例')],
    [sg.Image(filename='', pad=(25,25), key='cam1')]
]
window=sg.Window('window1', layout, alpha_channel=1)

# 並行処理
def multi(x):
    return x['img']

pool=ProcessPoolExecutor()
for x in xs:
    # <DEBUG>
    if x=={}:
        continue
    result=pool.submit(multi, x)
    event, _=window.read(timeout=1)
    if event == sg.WIN_CLOSED:
        break
    imgbytes=cv2.imencode('.png', result.result())[1].tobytes()
    window['cam1'].update(data=imgbytes)

# window close
window.close()
print('終了します')
SETTING MANAGERを用いる場合

チェックするポイントは赤丸してあるところです。

FACE01 GRAPHICSが入力動画を認識しない

ffmpegがインストールされていない場合はこれをインストールして下さい。

$ sudo apt install ffmpeg

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

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

下のようになっていたら動画入力できない状態です。

(…中略)

 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)

(…後略)

この場合ライブラリを再インストールする必要があります。強制的に再インストールするには以下のようにして下さい。

$ pip3 install --force-reinstall opencv-python

Python仮想環境であればvenvで作成されたフォルダを削除後ライブラリをインストールすれば良いので簡単です。

システムのPython実行環境をお使いの場合も同様に–force-reinstallすれば通常はOKです。

パッケージ管理システムの場合、openCV は python3-opencv です。競合を避けるため先にpipからインストールしたopencvをアンインストールして下さい。

$ pip3 uninstall opencv-python
$ sudo apt install python3-opencv

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

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

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

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

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

まとめ

今回はFACE01が起動しないところから速度に直接関係する引数指定をカバーしました。

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

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

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