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

Natural Software

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

Kinect for Windows SDK beta で遊んでみた 〜 C++でOpenCV対応 〜 #shibuya_ni

Kinect


公式SDKC++サンプルはDirect3Dっぽいので、もっと気軽に遊べるようにOpenCVで表示させてみました。
OpenCV対応はこちらを参考にしています。ありがとうございます:-)

環境

ビルド手順

  1. Visual Studioを立ち上げ、コンソールプロジェクトを作成します
  2. インクルードパスにSDKOpenCVのパスを追加します
    • $(MSRKINECTSDK)\inc
    • C:\OpenCV2.2\include
  3. ライブラリパスにもSDKOpenCVのパスを追加します
    • $(MSRKINECTSDK)\lib
    • C:\OpenCV2.2\lib
  4. ライブラリにSDKOpenCVを追加します
    • MSRKinectNUI.lib
    • opencv_core220d.lib
    • opencv_highgui220d.lib
  5. 次のコードを入力して、ビルドします
// カメラ画像を表示するサンプル
#include <iostream>

// MSR_NuiApi.hの前にWindows.hをインクルードする
#include <Windows.h>
#include <MSR_NuiApi.h>

#include <opencv2/opencv.hpp>

#define ERROR_CHECK( ret )  \
    if ( ret != S_OK ) {    \
        std::cout << "failed " #ret " " << ret << std::endl;    \
        exit( 1 );          \
    }


void main()
{
    // 初期化
    ERROR_CHECK( ::NuiInitialize( NUI_INITIALIZE_FLAG_USES_COLOR ) );

    // カメラハンドルの取得
    HANDLE imageEvent = ::CreateEvent( 0, TRUE, FALSE, 0 );
    HANDLE streamHandle = 0;
    NUI_IMAGE_RESOLUTION resolution = NUI_IMAGE_RESOLUTION_640x480;
    ERROR_CHECK( ::NuiImageStreamOpen( NUI_IMAGE_TYPE_COLOR, resolution,
                    0, 2, imageEvent, &streamHandle ) );

    // 画面サイズを取得
    DWORD x = 0, y = 0;
    ::NuiImageResolutionToSize( resolution, x, y );

    // OpenCVの初期設定
    char* windowName = "camera_image";
    ::cvNamedWindow( windowName );
    cv::Ptr< IplImage > videoImg = ::cvCreateImage( cvSize( x, y ), IPL_DEPTH_8U, 4 );

    // メインループ
    while ( 1 ) {
        // データの更新を待つ
        ::WaitForSingleObject( imageEvent, INFINITE );

        // カメラデータの取得
        CONST NUI_IMAGE_FRAME *imageFrame = 0;
        ERROR_CHECK( ::NuiImageStreamGetNextFrame( streamHandle, 0, &imageFrame ) );

        // 画像データの取得
        KINECT_LOCKED_RECT rect;
        imageFrame->pFrameTexture->LockRect( 0, &rect, 0, 0 );

        // データのコピーと表示
        memcpy( videoImg->imageData, (BYTE*)rect.pBits, videoImg->widthStep * videoImg->height );
        ::cvShowImage( windowName, videoImg );

        // カメラデータの解放
        ERROR_CHECK( ::NuiImageStreamReleaseFrame( streamHandle, imageFrame ) );

        int key = ::cvWaitKey( 10 );
        if ( key == 'q' ) {
            break;
        }
    }

    // 終了処理
    NuiShutdown();

    ::cvDestroyAllWindows();
}

まとめ

サンプルはOpenNIと同じく、いろいろやってますが、ばらしてしまうとこんなもんです。
単純な使い方がわかると、いろいろ遊べそうですね:-)