【Mac】OpenCV, Dlibカスケード分類による顔認識いろいろ(C++, Python)

スポンサーリンク

近年の顔認識は、パソコンはもとより小型のマイコンボードなどの機器で実現できるようになってきており、顔認識を利用したアプリケーションは一般的になりました。

C++やPythonで簡単に試せる顔認識環境としてOpenCVとDlibが有名です。

本記事ではMacを使ってOpenCVとDlibそれぞれをC++/Python両言語で動かす方法と処理性能の比較結果を紹介します。

入力として、画像、動画、カメラ(リアルタイム)それぞれの場合の記述例を用意しました。

カメラ入力でリアルタイム処理を実行した際のOpenCV, Dlibとそれぞれの使用言語(C++, Python)との組み合わせの処理速度(FPS値)の比較結果は以下でした。(数値が大きいほど高速)

 OpenCVDlib
Machine 1Machine 2Machine 1Machine 2
C++7.114.05.49.3
Python7.014.59.19.8

※ Machine 1:MacBook Pro 13-inch Early 2015 / Dual Core i7 3.1GHz
  Machine 2:MacBook Pro 13-inch 2018 / Quad Core i7 2.7GHz

試行前はC++の方が速いだろうと予想していたのでPythonでも同程度かむしろ高速なのが意外でした。

OpenCVはQuad Coreの場合にDual Coreの2倍程度速くなっているので、CPUコア数に応じた並列化がなされている実装と推測できます。

DlibのPython版は、CPUコア数によらず比較的高速で、顔以外の部分を顔と誤認識することはほぼ無いので、この中ではDlib Python版がもっとも使いやすいです。

下の動画で、クリーンインストール直後のまっさらなMacで本記事の内容を試していますので、よろしければご覧ください。

使用環境

項目バージョン
macOSCatalina 10.15.7
Big Sur 11.2
OpenCV4.5.2
Dlib19.21

ソースコード(GitHub)

GitHubからソースコードをダウンロードします。

git clone https://github.com/tak6uch1/face_recognition
cd face_recognition

ディレクトリ構造は以下のようになっています。

face_recognition/
  cv_cpp/            : OpenCV C++
  cv_py/             : OpenCV Python
  dlib_cpp/          : Dlib C++
  dlib_py/           : Dlib Python

画像と動画のダウンロード

以下、私が試行に使用したファイルを紹介しますが、人の顔が写っていれば他のファイルで構いません。

以下のフリー画像をダウンロードします。

福岡県大刀洗町の採れたてリーフレタスをアピールする夫婦の写真素材|フリー素材は「ぱくたそ」写真を無料ダウンロード
福岡県大刀洗町の採れたてリーフレタスをアピールする夫婦の写真はレタス・サニーレタス・もんぺ・大刀洗に関連するのフリー素材です。高解像度(6071px×4047px)の写真素材を無料でダウンロードできます。

以下のフリー動画をダウンロードします。

Attention Required! | Cloudflare

サイズは一番小さいFull HDが良いです。

カスケード分類の種類

本記事で紹介するOpenCVとDlibはいずれもカスケード分類という技術を使って顔認識を行います。

カスケード分類器についてはこちらのサイトがわかりやすく、以下の3つの手法があり、OpenCVには1. Haar-Likeと2. LBPの顔認識モデルが最初から入っていました。

  1. Haar-Like特徴量
    物体の局所的な明暗差の組み合わせにより、画像を判別する
  2. LBP(Local Binary Pattern)特徴量
    物体の局所的な輝度の分布の組み合わせにより、画像を判別する
  3. HOG(Histogram of Oriented Gradients)特徴量
    物体の局所的な輝度の勾配方向の分布の組み合わせにより、画像を判別する

Dlibは3. HOGとSVM(サポートベクタマシン)が使われているとのことです。

環境構築

必要なツールのインストールから各環境でのコンパイルや実行方法について説明します。

以下の環境構築を実行するファイルを用意しており、./install_mac.shで、全実行することができますが、途中でエラーが発生する場合もあるかもしれませんので、1つずつ実行する方が安全だと思います。

HomeBrewをインストールしていない場合はインストールします。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

HomeBrewを使って必要となるツールをインストールします。

brew install wget
brew install boost
brew install boost-python3
brew install opencv
brew install cmake
brew install xquartz

xquartzのインストールでできたX11のシンボリックリンクを作成します。

ln -s /opt/X11/include/X11 /usr/local/include/X11

これを実施しないと画面表示がうまくいきませんでした。

次に/usr/local/bin/python3/usr/bin/python3よりも優先して使われるように~/.zshrcまたは~/.bash_profileにvi等のテキストエディタでPATH設定を追記します。

viの使い方に慣れていない方は、こちらの動画を参考にしてください。

vi ~/.zshrc

~/.zshrcの中身に以下を記述して保存します。

export PATH=/usr/local/bin:$PATH

現在起動しているターミナルで上記設定を有効にするためにsourceし、which python3で優先するpython3を確認し、以下のように/usr/local/bin/python3と表示されれば大丈夫です。

source ~/.zshrc
which python3
/usr/local/bin/python3

pip3を使ってimutilsをインストールします。

pip3 install imutils

Dlibをインストールします。

wget http://dlib.net/files/dlib-19.21.tar.bz2
tar zxf dlib-19.21.tar.bz2
cd dlib-19.21
sudo python3 setup.py install

PythonはAnaconda環境でも実行できます。その場合はこちらの記事を参考にPython 3.7※で仮想環境を立ち上げ、以下を実行します。

conda install opencv
pip install imutils

cd face_recognition/dlib-19.21
sudo python setup.py install

※2021/4/30現在、opencvはAnaconda Python 3.8環境に対応していないため、Python 3.7を選択します。Anacondaインストール直後でPython 3.7が選択肢に無い場合、「Update index…」ボタンを押すとすべてのPythonバージョンから選べるようになります。

Dlibで使用する顔のランドマークデータをダウンロードして展開します。

cd ..
wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
bunzip2 shape_predictor_68_face_landmarks.dat.bz2

OpenCV C++で顔認識

cv_cppディレクトリに移動します。

cd cv_cpp

ビルドディレクトリを作ってその下でcmakeを使ってビルドします。

mkdir build
cd build
cmake ..
cmake --build .

これでbuildディレクトリにimage, video, webcamができれば成功です。

あらかじめダウンロードした画像ファイルを与えてimageを実行します。

./image ~/Downloads/TC9V9A4577_TP_V4.jpg

以下のように顔に四角い枠が付けば成功です。

Face Detection of Image File

qを押すと終了します。

実行結果の画像は、output.jpgとして保存されます。

次に動画の顔認識を実行します。

./video ~/Downloads/video.mp4

以下のように顔に四角い枠が付けば成功です。

OpenCV Face Detection of Video File

顔ではない部分にマークが付くこともありますね。

ほぼ正面を向いている場合の認識率は良いですが、顔の一部が隠れたり、横向きや顔を傾けた場合に認識できないようです。

実行結果の動画はoutput.mp4として保存されます。

qを押すか、動画が終了するのを待ちます。

次ににパソコンのカメラ入力で顔認識を実行します。

./webcam

自分の顔に四角い枠が付けば成功です。

うまくいきましたでしょうか?

qを押して終了すると最後に以下のようにFPSを表示します。

FPS=7.1

7.1は私の実行結果で、1秒間に7.1フレームの処理ができたという意味です。

C++版はビルドに失敗することもあると思いますので、このページの下の方にあるトラブルシューティングも参考にしてください。

また、C++版がうまくいかなくても次のPython版は試せますので、あきらめずに挑戦してみてください。

OpenCV Pythonで顔認識

cv_pyディレクトリに移動します。(cv_cpp/buildにいる状態を想定しています)

cd ../../cv_py

以下のコマンドで画像入力の顔認識を実行します。

python3 image.py --image ~/Downloads/TC9V9A4577_TP_V4.jpg

以下のように顔に四角い枠が付けば成功です。

Fece Detection of Image File

qを押すと終了します。

実行結果の画像は、output.jpgとして保存されます。

次に以下のコマンドで動画の顔認識を実行します。

python3 video.py --video ~/Downloads/video.mp4

以下のように顔に四角い枠が付けば成功です。

OpenCV Face Detection of Video File

qを押すか、動画が終了するのを待ちます。

実行結果の動画は、output.mp4として保存されます。

次にパソコンのカメラ入力で顔認識位を実行します。

python3 webcam.py

自分の顔に四角い枠が付けば成功です。

Face Detection of Web Camera

うまく実行できましたでしょうか?

qを押して終了すると、C++版と同様にFPSを表示します。

FPS=7

Pythonはnumpyなど、C++で記述されたコンパイル済みのモジュールを呼び出して実行しているため、C++版と同程度の処理速度だったと思われます。

ビルド等の前処理が不要で同程度の処理速度であれば、通常はPython版を使うことで良いでしょう。

Dlib C++で顔認識

dlib_cppディレクトリに移動します。(cv_pyにいる状態を想定しています)

cd ../dlib_cpp

buildディレクトリを作ってその下でcmakeを使ってビルドします。

mkdir build
cd build
cmake ..
cmake --build .

学習済みモデルデータへのシンボリックリンクを作成します。

ln -s ../../shape_predictor_68_face_landmarks.dat

Xquartzを起動します。

Launch Xquartz

Xquartzを起動しても何も表示されないため心配になるかもしれませんが、問題ないので次に進みます。

以下のコマンドで画像ファイル入力の顔認識を実行します。

./image_dlib ~/Downloads/TC9V9A4577_TP_V4.jpg

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。

Dlib Face Recognition of Image File

ウィンドウの✕印またはターミナル上でCtrl+cで終了します。

実行結果の画像はoutput.jpgに保存されます。(顔のパーツ認識結果は保存していません)

次に動画の顔認識を実行します。

./video_dlib ~/Downloads/video.mp4

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。

Dlib Face Detection of Video File

OpenCVの顔認識と比べると顔ではない場所にマークが付くことはなく、認識精度は良いですね。

ウィンドウの✕印またはターミナル上でCtrl+cで終了します。

実行結果の動画はoutput.mp4に保存されます。(顔のパーツ認識結果は保存していません)

次にパソコンのカメラ入力で顔認識を実行します。

./webcam_dlib

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。(下図のGIF動画だとわかりづらいですが)

Dlib Face Detection of Webcam

うまくいきましたでしょうか?

顔を傾けたり、かなり横を向いたり、マスクをしても顔と認識してくれていて、OpenCVの場合よりも認識してくれる範囲が広いようです。

ウィンドウの✕印を押すと終了し、FPSを表示します。

FPS=5.4

Dlibでは顔のパーツを見つけてそこに顔があるという認識をしているようで、処理が複雑なだけOpenCVよりは遅くなったのかと予想します。

もし、C++版がうまくいかなくても次のPython版は試せますので、あきらめずに挑戦してみてください。

Dlib Pythonで顔認識

dlib_pyディレクトリに移動します。(dlib_cpp/builldにいる状態を想定しています)

cd ../../dlib_py

学習済みモデルデータへのシンボリックリンクを作成します。

ln -s ../shape_predictor_68_face_landmarks.dat

以下のコマンドで画像入力の顔認識を実行します。

python3 image_dlib.py --image ~/Downloads/TC9V9A4577_TP_V4.jpg

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。

Dlib Face Detection of Image File

qを押して終了します。

次に以下のコマンドで動画入力の顔認識を実行します。

python3 video_dlib.py --video ~/Downloads/video.mp4

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。

Dlib Face Detection of Video File

※この記事に貼り付けるために動画のサイズを小さくしてから顔認識を行いGIF動画化したので、緑のマークは相対的に大きく表現されています。

qを押して終了します。

次にパソコンのカメラ入力で顔認識を実行します。

python3 webcam_dlib.py

以下のように顔に対する赤い枠と目、鼻、口など顔のパーツに緑のマークが付きます。

Dlib Face Detection of Webcam

qを押して終了すると、FPSを表示します。

FPS=9.1

上記は私の実行例ですが、驚きの結果ではないでしょうか。

Dlib C++版より高速で、OpenCVよりも速いです。

Dlib Python版がnumpyなどのC++で記述されたPython用モジュールに適したアルゴリズムだったために、このような結果になったと推測します。

書籍紹介

Python、画像認識に関するおすすめの書籍を紹介します。

入門 Python 3

基礎から応用までわかりやすい説明でコード例も多数載っていて、初学者の入門書としては必要十分と感じています。

さらにPythonらしいコードの書き方も言及されていて、スマートなコードが書けるようになります。

詳解 OpenCV 3 ―コンピュータビジョンライブラリを使った画像処理・認識

最新のOpenCV4には対応していないのですが、やはりオライリー、基礎を学ぶには十分な情報があり、この本から入ることをおすすめします。

まとめ

MacでOpenCV、Dlibを利用し、画像/動画/カメラそれぞれの入力に対する顔認識を実施しました。

プログラム言語はC++とPythonを使いましたが、下表に示すFPS値のとおりPythonは同程度または高速でした。(数値が大きいほど高速)

 OpenCVDlib
Machine 1Machine 2Machine 1Machine 2
C++7.114.05.49.3
Python7.014.59.19.8

OpenCVはQuad Coreの場合に2倍程度速くなっているので、CPUコア数に応じた並列化がなされている実装なのかと推測できます。

DlibのPython版は、CPUコア数によらず比較的高速で、顔以外の部分を顔と誤認識することはほぼ無いので、この中ではDlib Python版がもっとも使いやすいです。

トラブルシューティング

cmakeでOpenCVにリンクできない

本記事の内容を実行する前にOpenCVをインストール済みであったり、以前はうまく実行できていたのに何らかの環境更新などで、cmakeに失敗する場合がありましたので、回避策を紹介します。

Mac$ cmake ..
CMake Error at CMakeLists.txt:6 (find_package):
  By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "OpenCV", but
  CMake did not find one.

  Could not find a package configuration file provided by "OpenCV" with any
  of the following names:

    OpenCVConfig.cmake
    opencv-config.cmake

  Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
  "OpenCV_DIR" to a directory containing one of the above files.  If "OpenCV"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!
See also "/Users/user/work/face_recognition/cv_cpp/build/CMakeFiles/CMakeOutput.log".

上記エラーが出た場合、このサイトの内容に従い、まずopencvのインストールを再度試すと以下のメッセージが出ます。

Mac$ brew install opencv
Warning: opencv 4.5.2 is already installed, it's just not linked.
To link this version, run:
  brew link opencv

brew link opencvを実行せよ、とのことなので、実行すると以下のようにエラーになります。

Mac$ brew link opencv
Linking /usr/local/Cellar/opencv/4.5.2... 
Error: Could not symlink lib/python3.9/site-packages/cv2/__init__.py
Target /usr/local/lib/python3.9/site-packages/cv2/__init__.py
already exists. You may want to remove it:
  rm '/usr/local/lib/python3.9/site-packages/cv2/__init__.py'

To force the link and overwrite all conflicting files:
  brew link --overwrite opencv

To list all files that would be deleted:
  brew link --overwrite --dry-run opencv

--overwriteを追加して以下のように実行すると無事リンクでき、cmakeも正常に動作するようになりました。

Mac$ brew link --overwrite opencv
Linking /usr/local/Cellar/opencv/4.5.2... 249 symlinks created.

dlibの画面表示に失敗する

初回のdlib実行時に画面が表示できない場合は、Xquartzを起動してから再度実行するとうまくいきました。

Input file: /Users/user/Downloads/TC9V9A4577_TP_V4.jpg
    5 FATAL [1] dlib.gui_core: Unable to connect to the X display.
Failed to initialize X11 resources

Pythonでimport cv2に失敗する

Pythonで以下のようにimport cv2ができないことがありました。

Traceback (most recent call last):
  File "image.py", line3, in <module>
    import cv2
ImportError: No module named cv2

/usr/local/bin/python3を優先する設定をせずにOpenCVのPythonプログラムを実行しようとした際にこのエラーが出ました。

~/.zshrcexport PATH=/usr/local/bin:$PATHを追加してsource ~/.zshrcをした後に実行することでエラーが出なくなりました。

Pythonでimport dlibに失敗する

Pythonで以下のようにimport dlibができないことがありました。

Traceback (most recent call last):
  File "/Users/user/face_recognition/dlib_py/image_dlib.py", line 1, in <module>
    import dlib
ModuleNotFoundError: No module named 'dlib'

環境構築の章で/usr/local/bin/python3を優先する設定をする前にsudo python3 setup.py installを実行すると上記のエラーが出ました。

~/.zshrcexport PATH=/usr/local/bin:$PATHを追加してsource ~/.zshrcをした後、再度sudo python3 setup.py installを実行するとエラーが出なくなりました。

OpenCV PythonでdetectMultiScaleのエラー

以下のエラーが出る場合の対処方法を説明します。

OpenCV(4.5.2) /tmp/opencv-20210402-71941-1bhz1nv/opencv-4.5.2/modules/objdetect/src/cascadedetect.cpp:1689: error: (-215:Assertion failed) !empty() in function 'detectMultiScale'

原因は、下記カスケードファイルの場所がお使いの環境と合っていないためと思われます。

C++の場合:

        // Cascade file for face detection
        const std::string cascade_name = "/usr/local/share/opencv4/lbpcascades/lbpcascade_frontalface.xml";

Pythonの場合:

    # Cascade file for face detection
    cascade_path = "/usr/local/share/opencv4/lbpcascades/lbpcascade_frontalface.xml"

以下のコマンドで見つけられると思いますので、見つかったファイルパスで上記”〜”の内容を置き換えてください。

find /usr/local -name lbpcascade_frontalface.xml

Anaconda環境をお使いの場合は以下のコマンドで見つかると思います。

find /Users/user/opt/anaconda3 -name lbpcascade_frontalface.xml

参考文献

タイトルとURLをコピーしました