NtKinect: Kinect V2 C++ Programming with OpenCV on Windows10

Kinect V2 で顔の詳細情報(HDFace)を認識する


2016.08.14: created by
2016.11.04: revised by
Japanese English
NtKinect.h version 1.4 以降に対応しているトピックスです。
NtKinect.h version 1.8 以降に対応している記述を含みます。
目次へ

前提として理解しておくべき知識


顔の詳細情報 HDFace の認識

モーションキャプチャ用に顔の詳細なデータ (HDFace) を取得します。


USE_FACE 定数を define してから NtKinect.h を include する と NtKinect の顔認識関係のメソッドや変数が有効になります。 NtKinect version1.4以降 ではさらに、顔の詳細情報 HDFace に関するメソッドや変数が有効になります。

NtKinect の顔の詳細情報 HDFace の認識に関するメソッド

返り値の型 メソッド名 説明
void setHDFace() version1.4以降。
setSkeleton()を呼び出した後に呼び出して顔の詳細情報 HDFace を認識することができる。
次のメンバ変数に値が設定される。
変数名説明
vector<vector<CameraSpacePoint>> hdfaceVertices顔の部品の位置
vector<UINT64> hdfaceTrackingId顔に対応する骨格のtrackingIdのベクタ
vector<pair<int,int>> hdfaceStatus顔の詳細認識の状態を表すFaceModelBuilderCollectionStatusとFaceModelBuilderCaptureStatusのペアのベクタ
pair<string,string> hdfaceStatusToString(pair<int,int>) version1.4以降。
顔モデルを作成するのに必要なデータの収集状況 hdfaceStatus[index ] を 引数として渡されると、状態を表す文字列のペアに変換する。
bool setHDFaceModelFlag(bool flag=false) version1.8以降。
「顔モデルを作成するのに必要なデータが十分に収集された時点で 顔のモデルを生成するかどうか」のフラグを設定する。
デフォルト値はfalseで「顔モデルを生成しない」。 関数の返り値はそれまでの設定値である。
この関数を引数trueで呼び出した後で setHDFace()関数を複数回呼び出すと、 必要な情報が収集された時点で個別の顔モデルを生成するようになる。 個別の顔モデルを生成すると詳細な顔(HDFace)認識の精度が上ることが期待される。
プログラムが不安定になることがあるので、この関数は実験的な扱いとする。

NtKinect の顔の詳細情報 HDFace の認識に関するメンバ変数

変数名 説明
vector<vector<CameraSpacePoint>> hdfaceVertices version1.4以降。
CameraSpace座標系における顔の部品の位置。
一人の人間の顔上の1347点の位置が vector<CameraSpacePoint> であり、
複数の人間を扱うため vector<vector<CameraSpacePoint>> となる。
vector<UINT64> hdfaceTrackingId version1.4以降。
trackingIdのベクタ。
hdfaceVertices[index ]に対応するtrackingIdが hdfaceTrackingId[index ]である。
vector<pair<int,int>> hdfaceStatus version1.4以降。
顔の認識状態。
一人の人間の顔情報 HDFace の認識状態が FaceModelBuilderCollectionStatus と FaceModelBuilderCaptureStatus のペアである pair<int,int>であり、 複数の人間を扱うため vector<pair<int,int>> となる。

FaceModelBuilderCollectionStatus

次の状態のORとなる。
FaceModelBuilderCollectionStatus 内の定数名
FaceModelBuilderCollectionStatus_ Complete 0
MoreFramesNeeded 0x2
LeftViewsNeeded 0x4
RightViewsNeeded 0x8
TiltedUpViewsNeeded 0x10

FaceModelBuilderCaptureStatus

次の状態のどれかとなる。
FaceModelBuilderCaptureStatus 内の定数名
FaceModelBuilderCaptureStatus_ GoodFrameCapture 0
OtherViewsNeeded 1
LostFaceTrack 2
FaceTooFar 3
FaceTooNear 4
MovingTooFast 5
SystemError 6
(注意)

Microsoftが配布しているサンプルではHDFace情報を得るためにはFaceModelBuilderを使って顔のモデルを生成していますが、 2016/08/14現在配布されている Kinect SDK v2.0_1409 では 私の手元の環境においてProduceFaceModel()関数の呼び出しがエラーとなり動作しません。

CComPtr faceModelData;
CComPtr  faceModel;
...
faceModelData->ProduceFaceModel(&faceModel));  // エラーとなる
この呼び出しを行わなくても詳細情報が取得できているので、NtKinectではProduceFaceModel()関数の呼び出しは省略しています。

この件に関して何か情報をお持ちの方はお知らせ下されば幸いです。 (2016/11/04 削除)

NtKinect version 1.8 で setHDFaceModelFlag(bool)関数を追加し、 個別の顔のモデルを生成するかどうかを選択できるようにしました。 ただし、個別の顔のモデルを生成する途中で例外を発生してプログラムが落ちることがありますので、 このフラグをtrueに設定するのは実験的扱いとさせて下さい。 (2016/11/04 追記)


プログラム作成の手順

  1. NtKinect: Kinect V2 で顔認識する(ColorSpace 座標系)」 の Visual Studio 2015 のプロジェクト KinectV2_face.zipを用いて作成します。
  2. このプロジェクトは次のように変更されているはずです。

  3. main.cppの内容を以下のように変更します。
  4. main.cpp
    #include <iostream>
    #include <sstream>
    
    #define USE_FACE
    #include "NtKinect.h"
    
    using namespace std;
    
    void putText(cv::Mat& img,string s,cv::Point p) {
      cv::putText(img, s, p, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255,0,0), 1, CV_AA);
    }
    
    string hexString(int n) { stringstream ss; ss << hex << n; return ss.str(); }
    
    void doJob() {
      NtKinect kinect;
      while (1) {
        kinect.setRGB();
        kinect.setSkeleton();
        for (auto person : kinect.skeleton) {
          for (auto joint : person) {
            if (joint.TrackingState == TrackingState_NotTracked) continue;
            ColorSpacePoint cp;
            kinect.coordinateMapper->MapCameraPointToColorSpace(joint.Position,&cp);
            cv::rectangle(kinect.rgbImage, cv::Rect((int)cp.X-5, (int)cp.Y-5,10,10), cv::Scalar(0,0,255),2);
          }
        }
        putText(kinect.rgbImage, "TrackingId", cv::Point(0, 30));
        putText(kinect.rgbImage, "Collection", cv::Point(0, 60));
        putText(kinect.rgbImage, "Capture", cv::Point(0, 90));
        putText(kinect.rgbImage, "Collection", cv::Point(0, 120));
        putText(kinect.rgbImage, "Capture", cv::Point(0, 150));
        kinect.setHDFace();
        for (int i=0; i<kinect.hdfaceVertices.size(); i++) {
          for (CameraSpacePoint sp : kinect.hdfaceVertices[i]) {
    	ColorSpacePoint cp;
    	kinect.coordinateMapper->MapCameraPointToColorSpace(sp,&cp);
    	cv::rectangle(kinect.rgbImage, cv::Rect((int)cp.X-1, (int)cp.Y-1, 2, 2), cv::Scalar(0,192, 0), 1);
          }
          int x = 200 * i + 150;
          auto status = kinect.hdfaceStatus[i];
          auto statusS = kinect.hdfaceStatusToString(status);
          putText(kinect.rgbImage, hexString(kinect.hdfaceTrackingId[i]), cv::Point(x, 30));
          putText(kinect.rgbImage, hexString(status.first), cv::Point(x, 60));
          putText(kinect.rgbImage, hexString(status.second), cv::Point(x, 90));
          putText(kinect.rgbImage, statusS.first, cv::Point(x, 120));
          putText(kinect.rgbImage, statusS.second, cv::Point(x, 150));
        }
        cv::imshow("hdface", kinect.rgbImage);
        auto key = cv::waitKey(1);
        if (key == 'q') break;
      }
      cv::destroyAllWindows();
    }
    
    int main(int argc, char** argv) {
      try {
        doJob();
      } catch (exception &ex) {
        cout << ex.what() << endl;
        string s;
        cin >> s;
      }
      return 0;
    }
    
    
  5. プログラムを実行するとRGB画像が表示されます。'q' キーで終了します。
  6. RGB画像の上に、認識された顔情報が表示されます。

    この例では、FaceModelBuilder の情報収集の状態(CollectionStatus, CaptureStatus)を個人ごとに画面上部に表示しています。 現在では、これらの状態は気にしなくてよいようです(未確認)。(2016/11/04 削除)




  7. サンプルのプロジェクトはこちら KinectV2_hdface.zip
  8. 上記のzipファイルには必ずしも最新の NtKinect.h が含まれていない場合があるので、 こちらから最新版をダウンロードして 差し替えてお使い下さい。


[実験]顔モデルを生成する(2016/11/04追記)

  1. NtKinect version 1.8 以降を利用している場合は、次の1行をmain.cppの先頭部分に加してみましょう。(緑字部分)
  2.   kinect.setHDFaceModelFlag(true);
    

    プログラムの先頭で1度だけ kinect.setHDFaceModelFlag(true) を呼び出しておくと、 FaceModelBuilder の情報収集が十分に行われた時点で顔モデルを生成します。 モデルを生成した方が、詳細な顔認識 (HDFace) の精度は上がります。 が、プログラムの動作が若干不安定になるため、現時点では顔モデルの生成を する状態は実験的扱いとします。 (2016/11/04 追記)

    main.cpp
    #include <iostream>
    #include <sstream>
    
    #define USE_FACE
    #include "NtKinect.h"
    
    using namespace std;
    
    void putText(cv::Mat& img,string s,cv::Point p) {
      cv::putText(img, s, p, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255,0,0), 1, CV_AA);
    }
    
    string hexString(int n) { stringstream ss; ss << hex << n; return ss.str(); }
    
    void doJob() {
      NtKinect kinect;
      kinect.setHDFaceModelFlag(true);
      while (1) {
        kinect.setRGB();
        kinect.setSkeleton();
        for (auto person : kinect.skeleton) {
          for (auto joint : person) {
            if (joint.TrackingState == TrackingState_NotTracked) continue;
            ColorSpacePoint cp;
            kinect.coordinateMapper->MapCameraPointToColorSpace(joint.Position,&cp);
            cv::rectangle(kinect.rgbImage, cv::Rect((int)cp.X-5, (int)cp.Y-5,10,10), cv::Scalar(0,0,255),2);
          }
        }
        putText(kinect.rgbImage, "TrackingId", cv::Point(0, 30));
        putText(kinect.rgbImage, "Collection", cv::Point(0, 60));
        putText(kinect.rgbImage, "Capture", cv::Point(0, 90));
        putText(kinect.rgbImage, "Collection", cv::Point(0, 120));
        putText(kinect.rgbImage, "Capture", cv::Point(0, 150));
        kinect.setHDFace();
        for (int i=0; i<kinect.hdfaceVertices.size(); i++) {
          for (CameraSpacePoint sp : kinect.hdfaceVertices[i]) {
    	ColorSpacePoint cp;
    	kinect.coordinateMapper->MapCameraPointToColorSpace(sp,&cp);
    	cv::rectangle(kinect.rgbImage, cv::Rect((int)cp.X-1, (int)cp.Y-1, 2, 2), cv::Scalar(0,192, 0), 1);
          }
          int x = 200 * i + 150;
          auto status = kinect.hdfaceStatus[i];
          auto statusS = kinect.hdfaceStatusToString(status);
          putText(kinect.rgbImage, hexString(kinect.hdfaceTrackingId[i]), cv::Point(x, 30));
          putText(kinect.rgbImage, hexString(status.first), cv::Point(x, 60));
          putText(kinect.rgbImage, hexString(status.second), cv::Point(x, 90));
          putText(kinect.rgbImage, statusS.first, cv::Point(x, 120));
          putText(kinect.rgbImage, statusS.second, cv::Point(x, 150));
        }
        cv::imshow("hdface", kinect.rgbImage);
        auto key = cv::waitKey(1);
        if (key == 'q') break;
      }
      cv::destroyAllWindows();
    }
    
    int main(int argc, char** argv) {
      try {
        doJob();
      } catch (exception &ex) {
        cout << ex.what() << endl;
        string s;
        cin >> s;
      }
      return 0;
    }
    
    
  3. プログラムを実行するとRGB画像が表示されます。"q"キーで終了します。
  4. 骨格が認識され、詳細な顔情報 (HDFace) が認識されると、RGB画像の上に顔情報が表示されます。

    顔が認識されている間に、ゆっくりと顔を上下左右に向けてみて下さい。 だんだんと顔情報が蓄積されていき十分に情報が収集された段階で顔のモデルが作成されます。

    顔モデル作成に必要な情報は画面左上の Status に表示されています。(Right とか Left とか Tilt とか...)

    顔モデルを作成している途中でエラーを出してプログラムが終了することがあります。 安定動作を優先する場合は setHdFaceModelFlag(true) は呼び出さないで下さい。

  5. サンプルのプロジェクトはこちら KinectV2_hdface2.zip
  6. 上記のzipファイルには必ずしも最新の NtKinect.h が含まれていない場合があるので、 こちらから最新版をダウンロードして 差し替えてお使い下さい。


HDFace で取得できる顔上の座標について

Kinect for Windows SDK 2.0 における顔の詳細情報 HDFace の認識に関する定義は以下の通りです。 HDFace で取得できる1347個の点のうちで重要な点は FaceFrameFeatures や HighDetailFacePoints の enum (列挙体) の中であらかじめ定義されています。

Kinect for Windows SDK 2.0 の Kinect.Face.h(抜粋)
typedef enum _FaceFrameFeatures FaceFrameFeatures;
enum _HighDetailFacePoints {
  HighDetailFacePoints_LefteyeInnercorner= 210,
  HighDetailFacePoints_LefteyeOutercorner= 469,
  HighDetailFacePoints_LefteyeMidtop= 241,
  HighDetailFacePoints_LefteyeMidbottom= 1104,
  HighDetailFacePoints_RighteyeInnercorner= 843,
  HighDetailFacePoints_RighteyeOutercorner= 1117,
  HighDetailFacePoints_RighteyeMidtop= 731,
  HighDetailFacePoints_RighteyeMidbottom= 1090,
  HighDetailFacePoints_LefteyebrowInner= 346,
  HighDetailFacePoints_LefteyebrowOuter= 140,
  HighDetailFacePoints_LefteyebrowCenter= 222,
  HighDetailFacePoints_RighteyebrowInner= 803,
  HighDetailFacePoints_RighteyebrowOuter= 758,
  HighDetailFacePoints_RighteyebrowCenter= 849,
  HighDetailFacePoints_MouthLeftcorner= 91,
  HighDetailFacePoints_MouthRightcorner= 687,
  HighDetailFacePoints_MouthUpperlipMidtop= 19,
  HighDetailFacePoints_MouthUpperlipMidbottom= 1072,
  HighDetailFacePoints_MouthLowerlipMidtop= 10,
  HighDetailFacePoints_MouthLowerlipMidbottom= 8,
  HighDetailFacePoints_NoseTip= 18,
  HighDetailFacePoints_NoseBottom= 14,
  HighDetailFacePoints_NoseBottomleft= 156,
  HighDetailFacePoints_NoseBottomright= 783,
  HighDetailFacePoints_NoseTop= 24,
  HighDetailFacePoints_NoseTopleft= 151,
  HighDetailFacePoints_NoseTopright= 772,
  HighDetailFacePoints_ForeheadCenter= 28,
  HighDetailFacePoints_LeftcheekCenter= 412,
  HighDetailFacePoints_RightcheekCenter= 933,
  HighDetailFacePoints_Leftcheekbone= 458,
  HighDetailFacePoints_Rightcheekbone= 674,
  HighDetailFacePoints_ChinCenter= 4,
  HighDetailFacePoints_LowerjawLeftend= 1307,
  HighDetailFacePoints_LowerjawRightend= 1327
};

typedef enum _HighDetailFacePoints HighDetailFacePoints;
enum _HighDetailFacePoints {
  HighDetailFacePoints_LefteyeInnercorner= 210,
  HighDetailFacePoints_LefteyeOutercorner= 469,
  HighDetailFacePoints_LefteyeMidtop= 241,
  HighDetailFacePoints_LefteyeMidbottom= 1104,
  HighDetailFacePoints_RighteyeInnercorner= 843,
  HighDetailFacePoints_RighteyeOutercorner= 1117,
  HighDetailFacePoints_RighteyeMidtop= 731,
  HighDetailFacePoints_RighteyeMidbottom= 1090,
  HighDetailFacePoints_LefteyebrowInner= 346,
  HighDetailFacePoints_LefteyebrowOuter= 140,
  HighDetailFacePoints_LefteyebrowCenter= 222,
  HighDetailFacePoints_RighteyebrowInner= 803,
  HighDetailFacePoints_RighteyebrowOuter= 758,
  HighDetailFacePoints_RighteyebrowCenter= 849,
  HighDetailFacePoints_MouthLeftcorner= 91,
  HighDetailFacePoints_MouthRightcorner= 687,
  HighDetailFacePoints_MouthUpperlipMidtop= 19,
  HighDetailFacePoints_MouthUpperlipMidbottom= 1072,
  HighDetailFacePoints_MouthLowerlipMidtop= 10,
  HighDetailFacePoints_MouthLowerlipMidbottom= 8,
  HighDetailFacePoints_NoseTip= 18,
  HighDetailFacePoints_NoseBottom= 14,
  HighDetailFacePoints_NoseBottomleft= 156,
  HighDetailFacePoints_NoseBottomright= 783,
  HighDetailFacePoints_NoseTop= 24,
  HighDetailFacePoints_NoseTopleft= 151,
  HighDetailFacePoints_NoseTopright= 772,
  HighDetailFacePoints_ForeheadCenter= 28,
  HighDetailFacePoints_LeftcheekCenter= 412,
  HighDetailFacePoints_RightcheekCenter= 933,
  HighDetailFacePoints_Leftcheekbone= 458,
  HighDetailFacePoints_Rightcheekbone= 674,
  HighDetailFacePoints_ChinCenter= 4,
  HighDetailFacePoints_LowerjawLeftend= 1307,
  HighDetailFacePoints_LowerjawRightend= 1327
};

typedef enum _FaceShapeAnimations FaceShapeAnimations;
enum _FaceShapeAnimations {
  FaceShapeAnimations_JawOpen= 0,
  FaceShapeAnimations_LipPucker= 1,
  FaceShapeAnimations_JawSlideRight= 2,
  FaceShapeAnimations_LipStretcherRight= 3,
  FaceShapeAnimations_LipStretcherLeft= 4,
  FaceShapeAnimations_LipCornerPullerLeft= 5,
  FaceShapeAnimations_LipCornerPullerRight= 6,
  FaceShapeAnimations_LipCornerDepressorLeft= 7,
  FaceShapeAnimations_LipCornerDepressorRight= 8,
  FaceShapeAnimations_LeftcheekPuff= 9,
  FaceShapeAnimations_RightcheekPuff= 10,
  FaceShapeAnimations_LefteyeClosed= 11,
  FaceShapeAnimations_RighteyeClosed= 12,
  FaceShapeAnimations_RighteyebrowLowerer= 13,
  FaceShapeAnimations_LefteyebrowLowerer= 14,
  FaceShapeAnimations_LowerlipDepressorLeft= 15,
  FaceShapeAnimations_LowerlipDepressorRight= 16,
  FaceShapeAnimations_Count= ( FaceShapeAnimations_LowerlipDepressorRight + 1 ) 
};

typedef enum _FaceShapeDeformations FaceShapeDeformations;
enum _FaceShapeDeformations {
  FaceShapeDeformations_PCA01= 0,
  FaceShapeDeformations_PCA02= 1,
  FaceShapeDeformations_PCA03= 2,
  FaceShapeDeformations_PCA04= 3,
  FaceShapeDeformations_PCA05= 4,
  FaceShapeDeformations_PCA06= 5,
  FaceShapeDeformations_PCA07= 6,
  FaceShapeDeformations_PCA08= 7,
  FaceShapeDeformations_PCA09= 8,
  FaceShapeDeformations_PCA10= 9,
  FaceShapeDeformations_Chin03= 10,
  FaceShapeDeformations_Forehead00= 11,
  FaceShapeDeformations_Cheeks02= 12,
  FaceShapeDeformations_Cheeks01= 13,
  FaceShapeDeformations_MouthBag01= 14,
  FaceShapeDeformations_MouthBag02= 15,
  FaceShapeDeformations_Eyes02= 16,
  FaceShapeDeformations_MouthBag03= 17,
  FaceShapeDeformations_Forehead04= 18,
  FaceShapeDeformations_Nose00= 19,
  FaceShapeDeformations_Nose01= 20,
  FaceShapeDeformations_Nose02= 21,
  FaceShapeDeformations_MouthBag06= 22,
  FaceShapeDeformations_MouthBag05= 23,
  FaceShapeDeformations_Cheeks00= 24,
  FaceShapeDeformations_Mask03= 25,
  FaceShapeDeformations_Eyes03= 26,
  FaceShapeDeformations_Nose03= 27,
  FaceShapeDeformations_Eyes08= 28,
  FaceShapeDeformations_MouthBag07= 29,
  FaceShapeDeformations_Eyes00= 30,
  FaceShapeDeformations_Nose04= 31,
  FaceShapeDeformations_Mask04= 32,
  FaceShapeDeformations_Chin04= 33,
  FaceShapeDeformations_Forehead05= 34,
  FaceShapeDeformations_Eyes06= 35,
  FaceShapeDeformations_Eyes11= 36,
  FaceShapeDeformations_Nose05= 37,
  FaceShapeDeformations_Mouth07= 38,
  FaceShapeDeformations_Cheeks08= 39,
  FaceShapeDeformations_Eyes09= 40,
  FaceShapeDeformations_Mask10= 41,
  FaceShapeDeformations_Mouth09= 42,
  FaceShapeDeformations_Nose07= 43,
  FaceShapeDeformations_Nose08= 44,
  FaceShapeDeformations_Cheeks07= 45,
  FaceShapeDeformations_Mask07= 46,
  FaceShapeDeformations_MouthBag09= 47,
  FaceShapeDeformations_Nose06= 48,
  FaceShapeDeformations_Chin02= 49,
  FaceShapeDeformations_Eyes07= 50,
  FaceShapeDeformations_Cheeks10= 51,
  FaceShapeDeformations_Rim20= 52,
  FaceShapeDeformations_Mask22= 53,
  FaceShapeDeformations_MouthBag15= 54,
  FaceShapeDeformations_Chin01= 55,
  FaceShapeDeformations_Cheeks04= 56,
  FaceShapeDeformations_Eyes17= 57,
  FaceShapeDeformations_Cheeks13= 58,
  FaceShapeDeformations_Mouth02= 59,
  FaceShapeDeformations_MouthBag12= 60,
  FaceShapeDeformations_Mask19= 61,
  FaceShapeDeformations_Mask20= 62,
  FaceShapeDeformations_Forehead06= 63,
  FaceShapeDeformations_Mouth13= 64,
  FaceShapeDeformations_Mask25= 65,
  FaceShapeDeformations_Chin05= 66,
  FaceShapeDeformations_Cheeks20= 67,
  FaceShapeDeformations_Nose09= 68,
  FaceShapeDeformations_Nose10= 69,
  FaceShapeDeformations_MouthBag27= 70,
  FaceShapeDeformations_Mouth11= 71,
  FaceShapeDeformations_Cheeks14= 72,
  FaceShapeDeformations_Eyes16= 73,
  FaceShapeDeformations_Mask29= 74,
  FaceShapeDeformations_Nose15= 75,
  FaceShapeDeformations_Cheeks11= 76,
  FaceShapeDeformations_Mouth16= 77,
  FaceShapeDeformations_Eyes19= 78,
  FaceShapeDeformations_Mouth17= 79,
  FaceShapeDeformations_MouthBag36= 80,
  FaceShapeDeformations_Mouth15= 81,
  FaceShapeDeformations_Cheeks25= 82,
  FaceShapeDeformations_Cheeks16= 83,
  FaceShapeDeformations_Cheeks18= 84,
  FaceShapeDeformations_Rim07= 85,
  FaceShapeDeformations_Nose13= 86,
  FaceShapeDeformations_Mouth18= 87,
  FaceShapeDeformations_Cheeks19= 88,
  FaceShapeDeformations_Rim21= 89,
  FaceShapeDeformations_Mouth22= 90,
  FaceShapeDeformations_Nose18= 91,
  FaceShapeDeformations_Nose16= 92,
  FaceShapeDeformations_Rim22= 93,
  FaceShapeDeformations_Count= ( FaceShapeDeformations_Rim22 + 1 ) 
};

typedef enum _FaceAlignmentQuality FaceAlignmentQuality;
enum _FaceAlignmentQuality {
  FaceAlignmentQuality_High= 0,
  FaceAlignmentQuality_Low= 1
};

typedef enum _FaceModelBuilderCollectionStatus FaceModelBuilderCollectionStatus;
enum _FaceModelBuilderCollectionStatus {
  FaceModelBuilderCollectionStatus_Complete= 0,
  FaceModelBuilderCollectionStatus_MoreFramesNeeded= 0x1,
  FaceModelBuilderCollectionStatus_FrontViewFramesNeeded= 0x2,
  FaceModelBuilderCollectionStatus_LeftViewsNeeded= 0x4,
  FaceModelBuilderCollectionStatus_RightViewsNeeded= 0x8,
  FaceModelBuilderCollectionStatus_TiltedUpViewsNeeded= 0x10
};

typedef enum _FaceModelBuilderCaptureStatus FaceModelBuilderCaptureStatus;
enum _FaceModelBuilderCaptureStatus {
  FaceModelBuilderCaptureStatus_GoodFrameCapture= 0,
  FaceModelBuilderCaptureStatus_OtherViewsNeeded= 1,
  FaceModelBuilderCaptureStatus_LostFaceTrack= 2,
  FaceModelBuilderCaptureStatus_FaceTooFar= 3,
  FaceModelBuilderCaptureStatus_FaceTooNear= 4,
  FaceModelBuilderCaptureStatus_MovingTooFast= 5,
  FaceModelBuilderCaptureStatus_SystemError= 6
};

typedef enum _FaceModelBuilderAttributes FaceModelBuilderAttributes;
enum _FaceModelBuilderAttributes {
  FaceModelBuilderAttributes_None= 0,
  FaceModelBuilderAttributes_SkinColor= 0x1,
  FaceModelBuilderAttributes_HairColor= 0x2
};


http://nw.tsuda.ac.jp/