金曜日にリリースされて、みなさん土日でたくさん遊んでたみたいで、若干出遅れ感があるのですが、MS Kinect公式SDKのカメラ、距離、ユーザーあたりを遊んでみました。上の画像は、カメラ画像にユーザーと骨格をマッピングしたものです。
OpenCV対応はこちらを参考にしています。ありがとうございます:-)
ここいらへんもぼちぼち更新してます
- KINECT for Windows SDK と OpenNI の比較 - かおるんダイアリー
- Kinect for Windows SDK beta で遊んでみた #shibuya_ni - かおるんダイアリー
環境
- Windows 7 x64
- Visual Studio 2010 Premium
- OpenCV2.2
- ここのインストーラからインストールした。OpenCV download | SourceForge.net
- 公式SDK
- ソース
OpenCVと公式SDKをデフォルトのパスでインストールして、ソースのkinect_sdk_samples.slnを開いてビルドすれば動くと思います。
やったこと
- カメラ画像をOpenCVで表示する
- デプスマップを表示する
- カメラ画像に、ユーザーを重ね合わせる
- カメラ画像に、ユーザーとボーンを重ね合わせる
公式SDKのC++ライブラリは、単体で使用するときはC,複数のKinectを扱うときはCOMインタフェースを使うようです。C#のほうをみると、COMインタフェースをラップした形になっているようなので、それに合わせてC++のほうも(自分が)使いやすくしてみました。今のとこカメラとユーザーの重ね合わせはこんな感じで書けるようになっています。
結構OpenNIと似てますね。同じデバイスを使ってるので、よくよく考えると当然なのかもしれません。
// 中心の距離を表示するサンプル #include <iostream> #include <sstream> #include "kinect\nui\Kinect.h" #include "kinect\nui\ImageFrame.h" #include <opencv2/opencv.hpp> // ユーザーの色づけ const UINT colors[] = { 0xFFFFFFFF, // ユーザーなし 0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000, }; void main() { try { kinect::nui::Kinect kinect; kinect.Initialize( NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON ); kinect::nui::ImageStream& video = kinect.VideoStream(); video.Open( NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480 ); kinect::nui::ImageStream& depth = kinect.DepthStream(); depth.Open( NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, NUI_IMAGE_RESOLUTION_320x240 ); // OpenCVの初期設定 char* windowName = "player"; ::cvNamedWindow( windowName ); cv::Ptr< IplImage > playerImg = ::cvCreateImage( cvSize(video.Width(), video.Height()), IPL_DEPTH_8U, 4 ); while ( 1 ) { // データの更新を待つ kinect.WaitAndUpdateAll(); // 次のフレームのデータを取得する(OpenNIっぽく) kinect::nui::VideoFrame videoMD( video ); kinect::nui::DepthFrame depthMD( depth ); // データのコピーと表示 UINT* img = (UINT*)playerImg->imageData; for ( int y = 0; y < videoMD.Height(); ++y ) { for ( int x = 0; x < videoMD.Width(); ++x, ++img ) { *img = videoMD( x, y ) & colors[depthMD( x / 2, y / 2 ) & 0x7]; } } ::cvShowImage( windowName, playerImg ); int key = ::cvWaitKey( 10 ); if ( key == 'q' ) { break; } } ::cvDestroyAllWindows(); } catch ( std::exception& ex ) { std::cout << ex.what() << std::endl; } }
気づいたこと
- キャリブレーションのポーズをしないで骨格が取れるのは画期的
- VMで動かない(おそらくわざと制限をかけている)。MacのBootCampはOK
- Kinect SDKはカメラが1280x1024か640x480で、デプス(ユーザー検出)が320x240か80x60なので、一工夫しないと、カメラ画像にユーザーを重ねるのができない
- ViewPointの設定がないので、カメラとデプスがずれる
- Mirrorの設定がないので、鏡の画像しかとれない
- RecordとPlayerがないので、記録と再生はできない
- カメラと距離でに関しては、OpenNIのうちGeneratorとMetaData相当といった感じ(Capabilityやコールバックがない)。もちろんNITE相当もない
- Audioをがんばりすぎて、イメージとデプスはおざなりになってる印象
次
- これ( Kinect SDK XNA 取得した骨格情報に追従してカメラ角度を変更 - Kosaka laboratory Interactive System tips )が楽しそうなのでC++でやってみる
- 音関係