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

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


2016.07.16: created by
Japanese English
目次へ

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


顔の認識

顔の向き(pitch, yaw, roll) を数値で表示します。

また、顔の状態(笑っているか、正面を見ているか、眼鏡をかけているか、 左目を閉じているか、右目を閉じているか、口が開いているか、口が動いているか、他を見ているか) を unknown, no, maybe, yes の4段階で判断して表示します。

表示場所を顔の矩形領域のすぐ下とするとどの顔の状態かがわかりやすいのですが、 表示位置が動いて読みづらくなるので、今回は画面の上方の固定位置に表示することにします。


プログラム作成の手順

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

  3. main.cppの内容を以下のように変更します。
  4. main.cpp
    #include <iostream>
    #include <sstream>
    
    #define USE_FACE
    #include "NtKinect.h"
    
    using namespace std;
    
    string faceProp[] = {
      "happy", "engaed", "glass", "leftEyeClosed",
      "rightEyeClosed", "mouseOpen", "mouseMoved", "lookingAway"
    };
    string dstate[] = { "unknown", "no", "maybe", "yes" };
    
    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);
          }
        }
        for (int p = 0; p < kinect.faceDirection.size(); p++) {
          cv::Vec3f dir = kinect.faceDirection[p];
          cv::putText(kinect.rgbImage, "pitch : " + to_string(dir[0]), cv::Point(200 * p + 50, 30), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0,230,0), 1, CV_AA);
    // rename CV_AA as cv::LINE_AA  (in case of opencv3 and later)
          cv::putText(kinect.rgbImage, "yaw : " + to_string(dir[1]), cv::Point(200 * p + 50, 60), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0,230,0), 1, CV_AA);
          cv::putText(kinect.rgbImage, "roll : " + to_string(dir[2]), cv::Point(200 * p + 50, 90), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(0,230,0), 1, CV_AA);
        }
        for (int p = 0; p < kinect.faceProperty.size(); p++) {
          for (int k = 0; k < FaceProperty_Count; k++) {
            int v = kinect.faceProperty[p][k];
            cv::putText(kinect.rgbImage, faceProp[k] +" : "+ dstate[v], cv::Point(200 * p + 50, 30 * k + 120), cv::FONT_HERSHEY_SIMPLEX, 1.2, cv::Scalar(232,232,0), 1, CV_AA);
    
          }
        }
        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;
    }
    
  5. プログラムを実行するとRGB画像が表示されます。'q' キーで終了します。
  6. RGB画像の上に、認識された顔情報が表示されます。

    この例では、顔の向きと顔の状態を個人ごとに画面上部に表示します。




    ウィンドウの左上に顔の向き(pitch, yaw, roll) や表情を認識した項目が表示されています(字の色が薄くて読みにくいです。すみません。)。




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



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