LoginSignup
2

More than 5 years have passed since last update.

単一カメラで、顔の3Dモデルを得る

Last updated at Posted at 2018-12-21

顔の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で計算したほうがよい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2