読者です 読者をやめる 読者になる 読者になる

Natural Software

KinectなどのDepthセンサーを中心に活動しています

Kinect for Windows SDKのFaceTrackerで取れる2D座標を表示してみる(C++)

Kinect for Windows

FaceTrackingで取れる2Dデータを表示してみました(キモくてごめんなさいw)。

全体のコードはこちらにおいてあります。

2D座標を取得する

顔追跡の結果から顔の部位の座標(2D)を取得します。これにはIFTResult::Get2DShapePoints()を利用します。引数は以下の通りです。

  • FT_VECTOR2D**:部位の位置の配列を格納するFT_VECTOR2D*へのポインタ(FT_VECTOR2Dのポインタのポインタ)
  • UINT*:部位の数を格納するUINTへのポインタ

最初なんでFT_VECTOR2D**なのかなぁと不思議だったんですが(使用例も見つからなかった)、内部的に持っているデータ列を返してくれるみたいですね。正常に取得できると、100点の座標を得ることができます。具体的な番号はこちらを参照ください(ここでは87点について書かれていますが、このほかに目の位置など13点の計100点が検出されます)。

FT_VECTOR2D* points;

UINT pointCount;

// 顔追跡(公開用)

void faceTracking()

{

// 顔追跡

HRESULT hr = faceTracking_p();

// 顔を見つけたので、追跡状態へ遷移

if(SUCCEEDED(hr) && SUCCEEDED(pFTResult->GetStatus())) {

::OutputDebugString( L"FaceTracking Success\n" );

isFaceTracked = true;

// 顔の領域を取得する

pFTResult->GetFaceRect( &faceRect );

// 2Dの座標を取得する

points = 0;

pointCount = 0;

hr = pFTResult->Get2DShapePoints( &points, &pointCount );

if( FAILED(hr) ) {

::OutputDebugString( L"Get2DShapePoints Failed\n" );

}

}

// 顔を見失ったので、未追跡状態のまま

else {

::OutputDebugString( L"FaceTracking failed\n" );

isFaceTracked = false;

}

}

点が取得できたら、それらを描画すると上記のような画像になります(ここでは顔の矩形を切り出して5倍に拡大しています)

const FT_VECTOR2D* points = kinect.get2DPoints();

for ( int i = 0; i < kinect.get2DPointCount(); ++i ) {

cv::circle( image, cv::Point(points[i].x, points[i].y), 1,

cv::Scalar( 0, 0, 255 ) );

}

cv::Mat out;

cv::resize( cv::Mat( image, cv::Rect(

cv::Point( kinect.FaceRect().left - 10, kinect.FaceRect().top - 10),

cv::Point( kinect.FaceRect().right + 10, kinect.FaceRect().bottom + 10)) ),

out, cv::Size(), 5, 5 );

cv::imshow( "Face", out );