【ラズパイ】Dlib顔認識を応用した電子工作/顔を傾けると旗が立つ C++, PythonでOpenCVとDlibを動かす方法も紹介

スポンサーリンク

本記事はMacで顔認識を試行した記事のRaspberry Pi版で、顔認識環境Dlibを応用した工作の作り方を紹介します。

カメラの画角の中央付近に顔が映っているとLEDが点灯し、さらにLEDが点灯中に顔を右に傾けるとサーボモーターが動いて旗を立てるという内容です。

また、Raspberry Pi(以降、ラズパイ)を使ってOpenCVとDlibそれぞれをC++/Python両言語で動かす方法についても紹介します。

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

Dlibは顔以外の部分を顔と誤認識することはほとんど無いので、使いやすいです。

下の動画で工作の実演やコードの解説をしていますので、よろしければご覧ください。

使用環境

以下の構成で本記事の内容を実施しました。

項目内容
Raspberry PiRaspberry Pi 4B
カメラ1. Pi Camera V2.1
2. USB Webカメラ
サーボモーターSG90
LED抵抗なしLED
抵抗LED用抵抗150Ω
ブレッドボードミニブレッドボード
配線ジャンパーワイヤー
安定化電源自作(参考ページ

ソースコード(GitHub)

GitHubからソースコードをダウンロードします。(使用するソースコードはMac版の記事と同じです)

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
  RPi_dlib_py_sample/ : Dlib Python sample for Raspberry Pi

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

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

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

福岡県大刀洗町の採れたてリーフレタスをアピールする夫婦の写真素材|フリー素材は「ぱくたそ」写真を無料ダウンロード
福岡県大刀洗町の採れたてリーフレタスをアピールする夫婦の写真はレタス・サニーレタス・もんぺ・大刀洗に関連するのフリー素材です。高解像度(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_linux1.sh
./install_linux2.sh
./install_linux3.sh

以降でOpenCVとDlibを試していきますが、すぐに工作を試したい方は、「Dlib Pythonを応用した電子工作」の章から試すことも可能です。

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

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

画像に alt 属性が指定されていません。ファイル名: webcam.gif

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

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

FPS=10

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

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=10.0

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

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

./image_dlib ~/Downloads/TC9V9A4577_TP_V4.jpg

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

Dlib Image

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

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

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

./video_dlib ~/Downloads/video.mp4

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

Dlib Video

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

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

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

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

./webcam_dlib

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

Dlib Face Detection of Webcam

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

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

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

FPS=3.2

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=3.5

上記は私の実行例で、Dlib C++版より少し高速でした。

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

Dlib Pythonを応用した電子工作

ラズパイを使った電子工作の回路図は以下となっています。

なお、ラズパイの電源、キーボード、マウス等は省略しています。

Circuit

ラズパイ用サンプルを格納したディレクトリに移動し、学習済みモデルデータへのシンボリックリンクを作成します。

cd ../RPi_dlib_sample
ln -s ../shape_predictor_68_face_landmarks.dat

以下のコマンドでサンプルプログラムを実行します。

python3 webcam_sample.py

画角の中央付近に顔があるときにLEDが点灯し、さらにLED点灯中に顔を右に傾けるとサーボモーターが動いて旗が立つという仕掛けです。

ラズパイ電子工作実施例

ちょっとした工作ですが、動きがあるのは楽しいですよね。

プログラムの仕組みを解説します。

顔ランドマークの27番〜30番が鼻の上の点であることがわかったので、これらの座標を利用しています。

30番が鼻の頭の方なので、画角の中心付近かどうかの判定に使っています。

そして、27番と30番を結ぶ線の傾きが一定以上になると旗を立てるという処理にしてあります。

前の章のwebcam_dlib.pyとの差分を見ると工作用に追記した部分がわかると思います。

書籍紹介

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

入門 Python 3

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

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

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

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

ゼロからよくわかる! ラズベリー・パイで電子工作入門ガイド Raspberry Pi 4 Model B対応[改訂2版]

ラズパイで電子工作するための入門書です。ラズパイや電子工作に興味はあるけれど、何から手を付けたらよいかわからない方におすすめします。

まとめ

ラズパイを使ってDlib顔認識を応用した工作を作りました。

内容としては、Pi Cameraの画角中心付近に顔があるときにLEDが点灯し、さらに顔を右に傾けるとサーボモーターが動いて旗が立つというものです。

ちょっとした工作ですし、完成度も低いですが、動きのある工作は見ていて楽しいですよね。

単なる顔認識でなく、顔認識結果によって何かさせることはいろいろな応用が考えられます。

みなさま独自のアイディアで楽しい工作にトライして頂けたらと思います。

トラブルシューティング

Pi Cameraを認識しない

環境構築の章のraspi-configの設定ができているかご確認ください。

また、端子の向きに間違いないかご確認ください。端子はHDMI端子がある方に向け、黒い部分を下に押し込むことで固定します。

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

参考文献

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