2013年8月4日日曜日

Kinect Basic Sample 01 RGB Camera View

Kinectを使って身体の研究をするプロジェクトの第一弾。 最も簡単なSample。 RGBカメラの表示。
#include <iostream>
#include <sstream>
// この順番でインクルード
#include <Windows.h>
#include <NuiApi.h>
#include <opencv2/opencv.hpp>
#define ERROR_CHECK( ret ) \
if ( ret != S_OK ) { \
std::cout << "failed " #ret " " << ret << std::endl; \
exit( 1 ); \
}
const NUI_IMAGE_RESOLUTION CAMERA_RESOLUTION = NUI_IMAGE_RESOLUTION_640x480;
class KinectSample{
private:
INuiSensor* kinect;
HANDLE imageStreamHandle;
DWORD width;
DWORD height;
public:
KinectSample();
~KinectSample();
public:
void initialize();
void run();
private:
void createInstance();
void drawRgbImage(cv::Mat& image);
};
KinectSample::KinectSample(){
}
// デストラクタ
KinectSample::~KinectSample(){
if(kinect != 0){
// Kinectの終了処理
kinect->NuiShutdown();
// Kinectのインスタンス開放処理
kinect->Release();
}
}
void KinectSample::initialize(){
createInstance();
// RGBカメラの使用
ERROR_CHECK(kinect->NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR));
//NUI_IMAGE_TYPE_COLORはRGBカメラの意味。解像度にCAMERA_RESOLUTION、ストリームハンドルのポインタを渡す
ERROR_CHECK(kinect->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, CAMERA_RESOLUTION, 0,2,0, &imageStreamHandle));
// 指定解像度の画面サイズを取得
::NuiImageResolutionToSize(CAMERA_RESOLUTION, width, height);
}
void KinectSample::run(){
cv::Mat image;
while(1){
drawRgbImage(image);
cv::imshow("Kinect Sample", image);
int key = cv::waitKey(10);
if(key == 'q'){
break;
}
}
}
void KinectSample::createInstance(){
int count = 0;
// Kinect接続数
ERROR_CHECK(::NuiGetSensorCount(&count));
if(count == 0){
throw std::runtime_error("Kinectを接続してください");
}
// 1台目 インデックス: 0 のキネクトインスタンスを作成
ERROR_CHECK(::NuiCreateSensorByIndex(0, &kinect));
HRESULT status = kinect->NuiStatus();
if(status != S_OK){
throw std::runtime_error("Kinect が利用可能ではありません");
}
}
// 更新されたフレームデータの取得&処理
void KinectSample::drawRgbImage(cv::Mat& image){
NUI_IMAGE_FRAME imageFrame = {0};
// 新しいフレームの取得(INFINETE タイムアウト無し(フレーム更新間に処理無し))
ERROR_CHECK(kinect->NuiImageStreamGetNextFrame(imageStreamHandle, INFINITE, &imageFrame));
// フレームの画像データ(更新画像データはpFrameTextureが持っていて、それをLockRectで呼び出してNUI_LOCKED_RECT型で取得する)
NUI_LOCKED_RECT colorData;
imageFrame.pFrameTexture->LockRect(0, &colorData, 0, 0);
// NUI_LOCKED_RECTの画像データをMat型にコピーする。データは1ピクセルあたり、8bitのRGBデータと無効値の4つであり、OpenCVではCV_8UC4と表現する。
// RGBはKinectとOpenCVで共通なので、そのままコピー可能。
image = cv::Mat(height, width, CV_8UC4, colorData.pBits);
// フレームを開放する
ERROR_CHECK(kinect->NuiImageStreamReleaseFrame(imageStreamHandle, &imageFrame));
}
void main(){
//Mat a;
try{
KinectSample kinect;
kinect.initialize();
kinect.run();
}catch(std::exception& ex){
std::cout << ex.what() << std::endl;
}
}

0 件のコメント:

コメントを投稿