NtKinect version1.2以前では、ColorSpace 座標系における座標としてしか取得できませんでしたが、 version1.3以降では顔の部品の位置を DepthSpace 座標系における座標としても取得できるようになりました。
返り値の型 | メソッド名 | 説明 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
void | setFace() | version1.2以前。 setSkeleton()を呼び出した後に呼び出して顔認識をすることができる。 次のメンバ変数に値が設定される。
|
|||||||||||||||
void | setFace(bool isColorSpace = true) | version1.3以降。 setSkeleton()を呼び出した後に呼び出して顔認識をすることができる。 次のメンバ変数に値が設定される。
第1引数をfalseで呼び出した場合はDepthSpace座標系における位置が変数にセットされる。 |
型 | 変数名 | 説明 |
---|---|---|
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 ] です。 |
データの種類によって、それを計測するセンサーの位置や解像度が異なります。 そのため、実世界での同じ位置の状態が、センサーによってそれぞれの座標系で表現された値として得られます。 異なるセンサーから得られたデータを同時に利用する場合は、 座標系の変換を行なってどちらかの座標系に合わせる必要があります。
Kinect V2 では、ColorSpace, DepthSpace, CameraSpace という3つの座標系があって、 それぞれの座標を表すデータ型 ColorSpacePoint, DepthSpacePoint, CameraSpacePoint が存在します。
Kinect for Windows SDK 2.0 の Kinect.h(抜粋) |
---|
typedef struct _ColorSpacePoint { float X; float Y; } ColorSpacePoint; typedef struct _DepthSpacePoint { float X; float Y; } DepthSpacePoint; typedef struct _CameraSpacePoint { float X; float Y; float Z; } CameraSpacePoint; |
RGB画像, Depth画像, 関節情報ではそれぞれ使っている座標系が異なります。 RGB画像の座標系は ColorSpace で、Depth画像の座標系は DepthSpace, 関節情報の座標系は CameraSpace です。
座標系 | 位置を表す型 | データの種類 |
---|---|---|
ColorSpace | ColorSpacePoint | RGB画像 |
DepthSpace | DepthSpacePoint | depth画像, bodyIndex画像, 赤外線画像 |
CameraSpace | CameraSpacePoint | skeleton情報 |
関節の位置を表すCameraSpace 座標系 |
---|
CameraSpace 座標系は、
(2016/11/12 図を変更し、説明を追記しました)。 |
Kinect V2 の ICoordinateMapper クラス が保持する「座標系の変換用メソッド」は次の通りです。
返り値の型 | メソッド名 | 説明 |
---|---|---|
HRESULT | MapCameraPointToColorSpace( CameraSpacePoint sp , ColorSpacePoint *cp ) |
CameraSpace 座標系での座標 sp を ColorSpace 座標系での座標に変換してcp にセットする。 返り値はS_OKかエラーコード。 |
HRESULT | MapCameraPointToDepthSpace( CameraSpacePoint sp , DelpthSpacePoint *dp ) |
CameraSpace 座標系での座標 sp を DepthSpace 座標系での座標に変換してdp にセットする。 返り値はS_OKかエラーコード。 |
HRESULT | MapDepthPointToColorSpace( DepthSpacePoint dp , UINT16 depth , ColorSpacePoint *cp ) |
DepthSpace 座標系での座標 dp と距離depth から ColorSpace 座標系での座標に変換してcp にセットする。 返り値はS_OKかエラーコード。 |
HRESULT | MapDepthPointToCameraSpace( DepthSpacePoint dp , UINT16 depth , CameraSpacePoint *sp ) |
DepthSpace 座標系での座標 dp と距離depth から CameraSpace 座標系での座標に変換してsp にセットする。 返り値はS_OKかエラーコード。 |
Kinect V2 で座標系の変換に使う ICoordinateMapper クラス のインスタンスは、 NtKinect のメンバ変数 coordinateMapper に保持されています。
型 | 変数名 | 説明 |
---|---|---|
CComPtr<ICoordinateMapper> | coordinateMapper | 座標変換を行う ICoordinateMapperのインスタンス。 |
このプロジェクトは次のように変更されているはずです。
Depth画像を取得します。
Depth画像の各ピクセルの値は CV_16UC1 (16bit幅のunsigned int 1個)で表現されているので、 カラーで書込みできる画像に変換します。 すなわち、一旦4500mmで最高の輝度(255)となるような CV_8UC1 (8bit幅の unsigned int 1個)に変換してから、 CV_8UC3 (8bit幅のunsigned int 3個, BGRフォーマット)に変換しています。
Depth画像の上に、DepthSpace 座標系で認識された顔の位置を書き込んでいます。
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; cv::Mat img8; cv::Mat img; while (1) { kinect.setDepth(); kinect.depthImage.convertTo(img8,CV_8UC1,255.0/4500); cv::cvtColor(img8,img,cv::COLOR_GRAY2BGR); kinect.setSkeleton(); for (auto person : kinect.skeleton) { for (auto joint : person) { if (joint.TrackingState == TrackingState_NotTracked) continue; DepthSpacePoint dp; kinect.coordinateMapper->MapCameraPointToDepthSpace(joint.Position,&dp); cv::rectangle(img, cv::Rect((int)dp.X-5, (int)dp.Y-5,10,10), cv::Scalar(0,0,255),2); } } kinect.setFace(false); for (cv::Rect r : kinect.faceRect) { cv::rectangle(img, r, cv::Scalar(255, 255, 0), 2); } for (vector<PointF> vf : kinect.facePoint) { for (PointF p : vf) { cv::rectangle(img, 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(img, "pitch : " + to_string(dir[0]), cv::Point(200 * p + 50, 30), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,255,255), 1, CV_AA); // rename CV_AA as cv::LINE_AA (in case of opencv3 and later) cv::putText(img, "yaw : " + to_string(dir[1]), cv::Point(200 * p + 50, 60), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,255,255), 1, CV_AA); cv::putText(img, "roll : " + to_string(dir[2]), cv::Point(200 * p + 50, 90), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,255,255), 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(img, faceProp[k] +" : "+ dstate[v], cv::Point(200 * p + 50, 30 * k + 120), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0,255,255), 1, CV_AA); } } cv::imshow("depth", img); 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; } |
Depth画像の上に、認識された顔情報が表示されます。
この例では、顔の向きと顔の状態を個人ごとに画面上部に表示します。
ウィンドウの左上に顔の向き(pitch, yaw, roll) や表情を認識した項目が表示されています。
上記のzipファイルには必ずしも最新の NtKinect.h が含まれていない場合があるので、 こちらから最新版をダウンロードして 差し替えてお使い下さい。