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

Kinect V2 で顔を認識する(ColorSpace 座標系)


2016.07.16: created by
Japanese English
目次へ

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


顔の認識

Kinect for Windows SDK 2.0 では顔認識に関しては次のように定義されています。

Kinect for Windows SDK 2.0 の Kinect.Face.h(抜粋)
enum _FacePointType {
    FacePointType_None= -1,
    FacePointType_EyeLeft= 0,
    FacePointType_EyeRight= 1,
    FacePointType_Nose= 2,
    FacePointType_MouthCornerLeft= 3,
    FacePointType_MouthCornerRight= 4,
    FacePointType_Count= ( FacePointType_MouthCornerRight + 1 ) 
};

enum _FaceProperty {
    FaceProperty_Happy= 0,
    FaceProperty_Engaged= 1,
    FaceProperty_WearingGlasses= 2,
    FaceProperty_LeftEyeClosed= 3,
    FaceProperty_RightEyeClosed= 4,
    FaceProperty_MouthOpen= 5,
    FaceProperty_MouthMoved= 6,
    FaceProperty_LookingAway= 7,
    FaceProperty_Count= ( FaceProperty_LookingAway + 1 ) 
};
Kinect for Windows SDK 2.0 の Kinect.h(抜粋)
enum _DetectionResult {
    DetectionResult_Unknown= 0,
    DetectionResult_No= 1,
    DetectionResult_Maybe= 2,
    DetectionResult_Yes= 3
};
Kinect for Windows SDK 2.0 の Kinect.h(抜粋)
typedef struct _PointF {
    float X;
    float Y;
} PointF;

USE_FACE 定数を define してから NtKinect.h を include する と NtKinect の顔認識関係のメソッドや変数が有効になります。

setSkeleton() 関数を呼び出して 骨格情報を取得した後に、setFace()メソッドを呼び出して顔を認識することができます。

NtKinect の顔認識に関するメソッド

返り値の型 メソッド名 説明
void setFace() version1.2以前。
setSkeleton()を呼び出した後に呼び出して顔認識をすることができる。
次のメンバ変数に値が設定される。
変数名説明
vector<vector<PointF>> facePoint顔の部品の位置
vector<cv::Rect> faceRect顔の矩形領域
vector<cv::Vec3f> faceDirection顔の向き
vector<vector<DetectionResult>> faceProperty顔の状態
void setFace(bool isColorSpace = true) version1.3以降。
setSkeleton()を呼び出した後に呼び出して顔認識をすることができる。
次のメンバ変数に値が設定される。
変数名説明
vector<vector<PointF>> facePoint顔の部品の位置
vector<cv::Rect> faceRect顔の矩形領域
vector<cv::Vec3f> faceDirection顔の向き
vector<vector<DetectionResult>> faceProperty顔の状態
引数を無し、または、第1引数をtrueで呼び出した場合はColorSpace座標系における位置が変数にセットされる。
第1引数をfalseで呼び出した場合はDepthSpace座標系における位置が変数にセットされる。

NtKinect の顔認識に関するメンバ変数

変数名 説明
vector<vector<PointF>> facePoint 顔の部品の位置。
一人の人間の「左目、右目、鼻、口の左端、口の右端」の位置が vector<PointF> であり、
複数の人間を扱うため vector<vector<PointF>> となる。
(version1.2以前)ColorSpace 座標系における位置である。
(version1.3以降)ColorSpace座標系またはDepthSpace座標系における位置である。
vector<cv::Rect> faceRect 顔の矩形領域のベクタ。
(version 1.2以前)ColorSpace 座標系における位置である。
(version1.3以降)ColorSpace座標系またはDepthSpace座標系における位置である。
vector<cv::Vec3f> faceDirection 顔の向き (pitch, yaw, roll) のベクタ
vector<vector<DetectionResult>> faceProperty 顔の状態。
一人の人間の「笑顔、正面、眼鏡、左目閉じる、右目閉じる、口が開く、口が動く、目をそらす」が
vector<DetectionResult> であり、 複数の人間を扱うため vector<vector<DetectionResult>> となる。
vector<UINT64> faceTrackingId version 1.4 以降で利用できる。
trackingIDのベクタ。
顔情報 faceRect[index ] などに対応する trackingIdは faceTrackingId[index ] です。

骨格認識されたすべての人間の顔が認識されるとは限りません。 「ある骨格が笑顔であるかどうか」など skeleton と face の対応を取りたい場合は、 skeletonTrackingId[i] と faceTrackingId[j] が一致するかどうかで判定できます(version1.4以降)。 version1.3以前のNtKinectをお使いの場合は、 骨格認識で得た顔の位置 kinect.skeleton[i][JointType_Head] が、顔認識で得られた顔の矩形領域 kinect.faceRect[j] の範囲内にあるかどうかで判定して下さい。


プログラム作成の手順

  1. NtKinect: Windows10上で Kinect V2 のプログラムを作成する (RGBカメラ画像)(基本設定)」 の Visual Studio 2015 のプロジェクト KinectV2.zipを用いて作成します。
  2. Kinect20.Face.lib ライブラリもリンクするように、プロジェクトを変更して下さい。
  3. ソリューションエクスプローラのプロジェクト名の上で右クリックしてメニューからプロパティを選択します。




    「構成プロパティ」の「リンカー」の「入力」の「追加の依存ファイル」を選択して、「編集」を選びます。




    Kinect20.Face.libを追加します。




  4. 実行時に必要なファイル(Kinect20.Face.dll)をコピーする必要があるため、 「構成プロパティ」->「ビルドイベント」->「ビルド後イベント」->「コマンドライン」 に次のコマンドを追加するように、プロジェクトを変更して下さい。
  5.   xcopy "$(KINECTSDK20_DIR)Redist\Face\x64" "$(OutDir)" /e /y /i /r
    



  6. main.cppの内容を以下のように変更します。
  7. NtKinect.h をinclude するよりも前に USE_FACE 定数をdefineして下さい。

    kinect.setSkeleton()メソッドを呼び出します。 プログラム例では kinect.skeleton を表示していますが、表示をする部分は省略しても構いません。 顔認識の前に kinect.setSkeleton()メソッドを呼び出して骨格認識をしておくことが重要です。

    setFace()メソッドを呼び出します。 kinect.faceRect, kinect.facePoint, kinect.faceProperty, kinect.faceDirection の値が設定されるので 必要に応じて表示します。

    main.cpp
    #include <iostream>
    #include <sstream>
    
    #define USE_FACE
    #include "NtKinect.h"
    
    using namespace std;
    
    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);
          }
        }
        kinect.setFace();
        for (cv::Rect r : kinect.faceRect) {
          cv::rectangle(kinect.rgbImage, r, cv::Scalar(255, 255, 0), 2);
        }
        for (vector<PointF> vf : kinect.facePoint) {
          for (PointF p : vf) {
            cv::rectangle(kinect.rgbImage, cv::Rect((int)p.X-3, (int)p.Y-3, 6, 6), cv::Scalar(0, 255, 255), 2);
          }
        }
        cv::imshow("rgb", 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;
    }
    
    
  8. プログラムを実行するとRGB画像が表示されます。'q' キーで終了します。
  9. RGB画像の上に、認識された顔情報が表示されます。

    この例では、顔の矩形領域をシアン色の四角形で表示し、 また顔の部品(左目、右目、鼻、口の左端、口の右端)の 位置に黄色の四角形を書いています。




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



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