2011/07/31

Kinect SDK(2) ~RGBカメラ利用編~

Kinect記事第二回です。

前回は、サンプルプログラムを動かすところまでをやりました。

今回は実際にプログラミングでKinectを扱ってみましょう!

ってな感じでサンプルプログラムを置いておきます。


以上のプログラムの実行結果はこのようになります。

モザイクがなんか犯罪者みたいだね!

さて、それではプログラムの詳しい説明をしていきます。

・include
KinectSDKを利用する場合はMSR_NuiApi.hをincludeします

・初期化関数
//Kinectの初期化関数
NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR);
Kinectの初期化関数となります。
引数に入れるフラグは以下のとおり

  • NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX
    • プレイヤーインデックス付きデプスマップを取得する場合
  • NUI_INITIALIZE_FLAG_USES_COLOR
    • RGBカメラ画像を使う場合
  • NUI_INITIALIZE_FLAG_USES_SKELETON
    • スケルトントラッキングを使う場合
  • NUI_INITIALIZE_FLAG_USES_DEPTH 
    • プレイヤーインデックスのないデプスマップを使う場合

これらのフラグを|(OR)でつなげて引数にいれます。
たとえば、スケルトントラッキングとプレイヤー付きデプスを使う場合
NUI_INITIALIZE_FLAG_USES_SKELETON | NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX
のように指定します。

・ハンドル設定
//各ハンドルの設定
m_hNextVideoFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_pVideoStreamHandle   = NULL;
各ハンドルを設定していきます。
意味のわからない人はオマジナイ程度で!

・RGBカメラの初期設定
カメラの初期設定を行います。 RGBカメラ、深度センサ共にNuiImageStreamOpenを利用して初期化をします。
第一引数には取得する画像の種類を指定します。主なものとしては

  • NUI_IMAGE_TYPE_COLOR
    • RGBカメラ画像
  • NUI_IMAGE_TYPE_DEPTH
    • デプスマップ
  • NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX
    • プレイヤーインデックス付きデプスマップ
などがあります。

・待機処理
画像が取得されるまで待機します。
もちろん、プログラムの作り方によっては待機しないほうがいい場合もあります。

・画像取得
int GetRGBImage(){
 //フレームを入れるクラス
 const NUI_IMAGE_FRAME * pImageFrame = NULL;

    HRESULT hr = NuiImageStreamGetNextFrame(m_pVideoStreamHandle, 30 , &pImageFrame );
    if( FAILED( hr ) ) return -1;//取得失敗

 //フレームから画像データの取得
    NuiImageBuffer * pTexture = pImageFrame->pFrameTexture;
    
 //ここからオマジナイ
 KINECT_LOCKED_RECT LockedRect;
    pTexture->LockRect( 0, &LockedRect, NULL, 0 );
    
 if( LockedRect.Pitch != 0 ){
  //pBitsに画像データが入っている
        BYTE * pBuffer = (BYTE*) LockedRect.pBits;
  memcpy(RGBImage->imageData,pBuffer,RGBImage->widthStep*RGBImage->height);
 }

    hr = NuiImageStreamReleaseFrame( m_pVideoStreamHandle, pImageFrame );
 if( FAILED( hr ) ) return -1;//取得失敗

 return 0;
}

この部分で重要な関数はこれです。

・NuiImageStreamGetNextFrame(m_pVideoStreamHandle, 30 , &pImageFrame );


で、画像のフレームを取得します。
第一引数は設定したストリームハンドル。
第二引数は画像が取得できてない場合に何ms待つか
第三引数は、画像情報が入るフレームのポインタとなります。
ImageFrameのメンバであるpFrameTextureを取得したのち
pFrameTextureのメンバ関数であるLockRectを呼び出します。
現時点ではこの辺はオマジナイ的なものみたいなので、キニシナイで大丈夫。(あとで色々実装されていくみたいです。)
KINECT_LOCKED_RECTのメンバであるpBitsに画像情報が入ってますのでOpenCVで使うIplImageにmemcpyしてあげて、表示させてあげれば画像情報を表示できます。

と、こんな感じでRGB表示ができるようになりました。わかりましたか?
よくわからない!って所があればコメント等どうぞです。

次回は、プレイヤー+デプスマップの取得をしたいと思います。


0 件のコメント:

コメントを投稿