でとりあえずwindows版とxbox版が手元に転がっていたのでこれらを使ってこれから遊んでいこうと思います。
試しにこのサンプルを使ってみます。
プレイヤーの認識とかは今回は使わないのでカットして、colorカメラの表示、depth座標をcolor座標に変換するのを加えてみました。
だいたいコピペです。
でも正しいかどうかは素人勉強中のためよくわかっていません。
プログラミングスキルもカスなのでご了承を。
逆にアドバイスもらえると嬉しいです。
環境:
windows7 64bit home premium
visual stadio 2013
openCV2.4.8
kinect for windows SDK v1.8
#include <Windows.h> #include <NuiApi.h> #include <iostream> #include <conio.h> #include <opencv2\opencv.hpp> using namespace std; using namespace cv; void main() { try { int count = 0; ::NuiGetSensorCount(&count); if (count == 0) { throw std::runtime_error("利用可能なKinectがありません"); } INuiSensor* kinect; ::NuiCreateSensorByIndex(0, &kinect); //変更 kinect->NuiInitialize(NUI_INITIALIZE_FLAG_USES_DEPTH | NUI_INITIALIZE_FLAG_USES_COLOR); //追加:colorHandle HANDLE depthHandle; HANDLE colorHandle; //追加 //depth kinect->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_640x480, 0, 2, 0, &depthHandle); //color kinect->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0, 2, 0, &colorHandle); DWORD width = 0; DWORD height = 0; ::NuiImageResolutionToSize(NUI_IMAGE_RESOLUTION_640x480, width, height); while (true) { // 距離カメラのフレームデータを取り出す NUI_IMAGE_FRAME depthFrame = { 0 }; kinect->NuiImageStreamGetNextFrame(depthHandle, INFINITE, &depthFrame); //追加:colorカメラのフレームデータを取り出す NUI_IMAGE_FRAME colorFrame = { 0 }; kinect->NuiImageStreamGetNextFrame(colorHandle, INFINITE, &colorFrame); // フレームデータを元に、拡張距離データを取得する BOOL nearMode = FALSE; INuiFrameTexture *frameTexture = 0; kinect->NuiImageFrameGetDepthImagePixelFrameTexture( depthHandle, &depthFrame, &nearMode, &frameTexture); //追加:color INuiFrameTexture *colorframeTexture = colorFrame.pFrameTexture; // NUI_DEPTH_IMAGE_PIXELを取り出す NUI_LOCKED_RECT rectDepth = { 0 }; //名前変えたrect→rectDepth frameTexture->LockRect(0, &rectDepth, 0, 0); //追加:カラー NUI_LOCKED_RECT rectColor = { 0 }; colorframeTexture->LockRect(0, &rectColor, 0, 0); NUI_DEPTH_IMAGE_PIXEL* depthPixel = (NUI_DEPTH_IMAGE_PIXEL*)rectDepth.pBits; // 表示する cv::Mat cameraDepth(height, width, CV_8UC3); //追加 cv::Mat cameraColor(height, width, CV_8UC4, reinterpret_cast<ushort*>(rectColor.pBits)); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int depthIndex = (y * width) + x; //追加 unsigned char iro = depthPixel[depthIndex].depth * 255 / 1000; //追加:depthとcolorの位置合わせ LONG colorX = 0; LONG colorY = 0; kinect->NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution( NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, nullptr, x, y, 0, &colorX, &colorY ); int cameraIndex = ((colorY * width) + colorX) * 3; //追加 //1mより遠い場合 if (depthPixel[depthIndex].depth > 1000) { cameraDepth.data[cameraIndex] = 0; cameraDepth.data[cameraIndex + 1] = 0; cameraDepth.data[cameraIndex + 2] = 0; } else{ // 1mより近い場合 cameraDepth.data[cameraIndex] = iro; cameraDepth.data[cameraIndex + 1] = iro; cameraDepth.data[cameraIndex + 2] = iro; } } } imshow("depth", cameraDepth); //追加:カラー表示 imshow("color", cameraColor); kinect->NuiImageStreamReleaseFrame(depthHandle, &depthFrame); //追加 kinect->NuiImageStreamReleaseFrame(colorHandle, &colorFrame); int key = cv::waitKey(10); if (key == 'q') { break; } } } catch (exception& ex) { cout << ex.what() << endl; } }
実行結果(あるフレームでの)
1mより先は黒で塗りつぶしています。
あと若干まだ座標のズレを感じます。距離画像の方が左に10画素くらい。
参考文献