This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 件のコメント:
コメントを投稿