Intel のデバイスを使う範囲だと、次の記事が紹介しているようにOpenVinoで顔向き推定ができます。
qiita AIを始めよう!OpenVINOで使うモデルを整備する
head-pos-estimation-adas-0001.xml のモデルデータを利用する。
github opencv /open_model_zoo head-pose-estimation-adas-0001
私見:顔向き推定は、顔の検出位置の正規化・顔ランドマークの検出に依存します。
ですから、よく使われる顔検出の正規化・顔ランドマークの検出にしたがった、顔向き推定を用いることです。
顔の属性推定や顔照合も、同様です。同一の枠組みを使うことが、全体としての処理のパフォーマンスを上げることにつながります。
dlibのlandmark を使うなどで、顔向き推定をしている記事やweb上のソースコードについて調査中です。
顔向き推定には、Perspective-n-Point algorithmのものとConvolutional Neural Networksによるものとを見つけています。
自分の目的に利用するためには、
顔向き推定がクラスベースの実装のなるようになどして、関連する処理が1つのクラスにまとめるのがよいと思います。
実装例1:回転行列を使う顔向き推定(使用するライブラリ、OpenCV, dlib)
-
Head Pose Estimation using OpenCV and Dlib
- ソースコードは"Download Code (C++ / Python)" を選択して、作者のページからメールを受け取ります。
- dlib のlandmark OpenCVで顔向き推定を行う
- この記事は上記の記事に対する解説記事です。pitch, yaw, roll の角度を求める部分の追加実装のしかたを書いてあります。
- この実装は顔器官点の座標を元に回転行列の値を推定することで顔の向きを推定するものです。
- web記事そのものの中では、顔器官点の2Dの座標を求める部分が書かれていません。dlibを使って顔器官点を求めるように書きなおす必要があります。以下の記事が参考になります。
- 用いられている数学については以下のOpenCVのチュートリアルが参考になります。 http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_calib3d/py_pose/py_pose.html
- http://planning.cs.uiuc.edu/node102.html
- http://planning.cs.uiuc.edu/node103.html
実装例:回転行列に基づく方法(使用するライブラリ、OpenCV, dlib)
$ cmake -DDLIB_PATH=<path to dlib> ..
を入力する際の<path to dlib>
にはgit clone https://github.com/davisking/dlib.git
で作成されたディレクトリを指定すればcmake, make が実行できました。
$ ./head_pose_test ../share/shape_predictor_68_face_landmarks.dat
とすればよいようです。入力はUSBカメラが使われます。
$ ./head_pose_single_frame ../share/shape_predictor_68_face_landmarks.dat input.jpg
こちらは静止画を入力とするものです。
いずれもC++のライブラリを使うプログラムになっています。
-
gazr
これも顔器官点から回転行列を求めて、顔向き推定をするものです。
実装例 (使用するライブラリ、OpenCV and dlib)
https://github.com/lincolnhard/head-pose-estimationn
これもdlibの顔器官点を使って、回転行列を求めている実装です。
solvepnp
実装例2:顔器官点を元にSVMで学習する顔向き推定(使用するライブラリ、OpenCV, dlib, scikit-learn)
顔器官点のデータを使ってSVMで学習しています。
SVMはscikit-learnを使っています。
clf = svm.SVC()
clf.fit(train_angles, train_labels) # 取得したデータで機械学習する
実装例3:顔器官点を元にDNNで学習する顔向き推定(使用するライブラリ, dlib, caffe)
-
本家のリポジトリにforked_versionからPRが反映されています。
-
python2.x を想定したものになっています。
-
たとえばprintは関数ではなくて文になっています。
-
requirement.txt の記載がないので、インストールが若干面倒です。
-
forked version: https://github.com/KatsunoriWa/head-pose-estimation-and-face-landmark
- dlib の顔検出、深層学習を利用して顔向きを推定。
- model ファイルをダウンロードする。 68point_dlib_with_pose.caffemodel VGG_mean.binaryproto
- 以下のコマンドを実行。
- $ python landmarkPredict.py predictImage testList.txt
- $ python python landmarkPredict_video.py 0
- FacePosePredictor class を導入して、再利用性を向上している。
オリジナルのguozhongluoのgit版で以下のエラーがでるときには、リストの添字が整数になるように修正を加えてください。
Traceback (most recent call last):
File "landmarkPredict.py", line 239, in <module>
func(*sys.argv[2:])
File "landmarkPredict.py", line 208, in predictImage
colorface = getRGBTestPart(bbox,M_left,M_right,M_top,M_bottom,colorImage,vgg_height,vgg_width)
File "landmarkPredict.py", line 83, in getRGBTestPart
face=img[retiBBox[2]:retiBBox[3],retiBBox[0]:retiBBox[1],:]
TypeError: slice indices must be integers or None or have an __index__ method
というエラーが出るときには、
# cv2.waitKey(0)
+ retiBBox = [int(round(x)) for x in retiBBox]
face=img[retiBBox[2]:retiBBox[3],retiBBox[0]:retiBBox[1],:]
の行を追加してみてください。
実装例:顔器官点を元にDNNで学習する顔向き推定(使用するライブラリ, TensorFlow 1.4, OpenCV 3.3, Python 3)
これもDNNベースの顔向き推定。
$ python estimate_head_pose.py
実装例:3種類の実装(OpenCV, tensorflow, dlib)
$ python examples/ex_pnp_head_pose_estimation_webcam.py
接続されたカメラから顔を検出し、head pose を3本の矢印で表示します。
その矢印の示す向きがいまいち安定していないような感じでした。
顔特徴点の抽出が安定していないのかもしれません。
また、ライブラリが書かれたときとOpenCVのpythonバインディングの実装が変化していたりするので、
fourcc = cv2.cv.CV_FOURCC(*'XVID')
AttributeError: 'module' object has no attribute 'cv'
といったエラーを生じるかもしれません。
その場合には、次のように変更すると動作します。
- fourcc = cv2.cv.CV_FOURCC(*'XVID')
+ fourcc = cv2.VideoWriter_fourcc(*'XVID')
$ python examples/ex_dlib_pnp_head_pose_estimation_video.py
You have to pass as argument the path to a video file and the path to the output file to produce, for example:
python ex_pnp_pose_estimation_video.py /home/video.mpg ./output.avi
$
$ python ex_cnn_head_pose_estimation_images.py
[DEEPGAZE] head_pose_estimation.py: the dlib library is installed.
Processing image ..... 1.jpg
Estimated [roll, pitch, yaw] ..... [-8.12711,-6.83478,7.2062]
Processing image ..... 2.jpg
Estimated [roll, pitch, yaw] ..... [-1.76577,-1.88228,54.2908]
Processing image ..... 3.jpg
Estimated [roll, pitch, yaw] ..... [-1.35001,-23.0703,-21.7094]
Processing image ..... 4.jpg
Estimated [roll, pitch, yaw] ..... [-3.89467,-12.0814,-53.7645]
Processing image ..... 5.jpg
Estimated [roll, pitch, yaw] ..... [0.411899,-1.7321,43.6103]
Processing image ..... 6.jpg
Estimated [roll, pitch, yaw] ..... [0.585647,-11.2426,-42.9941]
Processing image ..... 7.jpg
Estimated [roll, pitch, yaw] ..... [0.693526,-7.47962,-46.7058]
Processing image ..... 8.jpg
Estimated [roll, pitch, yaw] ..... [-1.19849,-8.18166,-24.7768]
$
StackOverflow How to get 3D coordinate Axes of head pose estimation in Dlib C++
顔向きによって検出器の性能がどのように違ってくるのかは
次のデータベースを使うことができます。
さらには、同一人物として照合可能な範囲がどの顔向きの範囲なのかを知るのに用いることもできるでしょう。
OpenFace
C++による実装
これもdlibの顔器官点を使っているようだ。
以下の記事の中では、顔向き推定を持つライブラリの比較が引用されている。
OpenFace中のリンクをたどると、動作例のYoutube動画にたどり着く。
- Qiita OpenFace について調査中
商用の場合は、コンタクトをとること。
innovation@cmu.edu
付記:
ここに示している実装の多くは、検出された顔に対して、次のステップで顔向き推定をするものになっています。
Deep Learning では1つのネットワークで、顔検出と同時に顔向き推定が可能であるとのことです。
その利点は、計算量の増加を抑えることができることが期待されます。
最近では、顔検出の商用ライブラリでもDeep Learning ベースの顔検出が増えてきていると聞いています。
追加
MATLABによる実装
Head detector
顔向きの推定を欲しがっている人は、その顔の人物がカメラ側を見ているのかどうか知りたくなることでしょう。
次の記事は有益でしょう。
付記 mediapipe による実装
mediapipeは、以下のdemoをweb上で動作させることができます。
顔検出だけではなく、顔のlandmark の検出もできます。
それだけできるのだから、head poseも出してもらえるとうれしいのに
Real Time Driver State Detection
Mediapipe を用いた顔向き推定も含むReal Time Driver State Detectionです。
リンク先のリポジトリに動画がありますので、それを見ると実装されている内容がわかります。
未調査
https://github.com/nullbyte91/head-pose-estimation