顔の3Dモデルを得るのに、高価な深度カメラやステレオカメラを使う必要はありません。汎用の安価な単一カメラ(英語だと、モノキュラーカメラ)でも可能です。
画像の複数フレームが必要なので、人の顔の映像(画像ストリーム)を得ていることを前提にします。
コードを載せると長すぎるので、処理の概略を載せておきます。
まず、OpenCVなどで、顔の特徴点を決め、画像フレームから特徴点を得られるようにしておきます。
###顔の特徴点のXY位置決め。
正面視時に、相続くフレームから特徴点位置が安定したフレーム群を得て、位置の平均を3DモデルのうちのXY位置とする。なお、人の顔のXYは、左右対称ではないですね。
###顔の特徴点のZ位置決め。
相続くフレームから特徴点位置が安定したフレーム群における特徴点の位置平均を、何個かサンプリングしてとっておく。これらをzモデルの評価に使う。
RANSAC方法で、最適なzを決め、先のxyに合わせて、3Dモデルとする。
RANSAC方法とは、仮説をランダムに生成して、評価することを繰り返して、最も評価値がよかったものを採用する、という方法です。具体的には、数百回ないしベストな評価値の改善具合がほとんどなくなるまで、以下を繰り返す。
1. モデル仮説生成:
唇は鼻の頂よりも奥にある、目頭は左右同じz、などというHeuristicsも利用して、特徴点群のもっともらしいz値をランダムに生成する。それで3D仮説とする。
2. モデル評価:
2.1. 3D仮説モデルをもとに、サンプルしておいた各フレームの特徴点群に対し、OpenCVを使い、以下を行う。
(1) FacePose(カメラと顔座標系の関係)を推定する。
(2) FacePoseを使い、3D仮説をカメライメージ平面に投影し、投影点と、フレーム内特徴点の実測位置と、の距離(誤差)の和を求める。
2.2. 各フレームの距離の和の合計を、この3Dモデルの評価値とする。
そして、最も評価値(誤差)の小さいモデルを採用する。
なお、特徴点位置とモデルからFacePoseが計算できる。2フレーム間で、FacePoseの含むカメラに対する顔の角度差と、特徴点位置差とから、三角関数を使って計算すれば、ある特徴点のZを得ることができる。その方法を試したが、いい結果が得られなかった。FacePoseはモデルに依存し、モデルの計算はFacePoseに依存するという循環がある上に、顔角度、特徴点位置いずれも誤差込々だし、zの値を安定させていくには、繰り返し法(日本人は、動的計画法を生み出したときから、繰り返し法が、好きみたいね)など複雑な手順が必要になる。それよりは、素早くRANSACで計算したほうがよい。