KinectのRecorder機能を使う
Kinectアプリのデバッグは一般的なアプリと違って、わざわざセンサーの前に立って毎回同じような動作をしなければなりません。
先日参加したハッカソンでも、みんなが急に立ち上がって色々動いたり、センサーに向かって手を振ったりと、かなりウケますw
けど、さすがに毎回立ち上がってと、デバッグをしていたら洒落になりません。
そこで便利機能として、Kinectセンサーから取得できた情報を保存して、再生することができます。
これを使えば、毎回立ち上がったり、手を振ったりする必要がなく、デバッグに集中することができます。
チームで開発する時は、各自にKinectを渡さなくても、環境さえ整えればプログラミングが出来て、経費節減にも繋がる!
main.cppの抜粋
1. xn::Recorder recorder; 2. if( DO_RECORED && !USE_RECORED_DATA ){ 3. // レコーダーの作成 4. LOG_I("%s", "Setup Recorder"); 5. nRetVal = recorder.Create(g_Context); 6. CHECK_RC(nRetVal, "Create recorder"); 7. 8. // 保存設定 9. nRetVal = recorder.SetDestination(XN_RECORD_MEDIUM_FILE, RECORD_FILE_PATH); 10. CHECK_RC(nRetVal, "Set recorder destination file"); 11. 12. // 深度、ビデオカメラ入力を保存対象として記録開始 13. nRetVal = recorder.AddNodeToRecording(g_DepthGenerator, XN_CODEC_NULL); 14. CHECK_RC(nRetVal, "Add depth node to recording"); 15. nRetVal = recorder.AddNodeToRecording(g_ImageGenerator, XN_CODEC_NULL); 16. CHECK_RC(nRetVal, "Add image node to recording"); 17. 18. LOG_I("%s", "Recorder setup done."); 19. } 20. 21. while (!xnOSWasKeyboardHit()) 22. { 23. g_Context.WaitOneUpdateAll(g_UserGenerator); 24. if( DO_RECORED && !USE_RECORED_DATA ){ 25. nRetVal = recorder.Record(); 26. CHECK_RC(nRetVal, "Record"); 27. }
簡単に説明すると、
・5行目のrecorder.Createでレコーダーを作成しています。
・9行目で、保存先を指定。
・13、15行目で保存するノードを指定します。
・25行目のrecorder.Record()で、毎回データを保存します。
という流れです。
逆に保存されたデータを読み込んで表示する方法は
1. g_Context.Init(); 2. g_Context.OpenFileRecording(RECORD_FILE_PATH); 3. xn::Player player; 4. 5. // PlayerNodeの取得 6. nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_PLAYER, player); 7. CHECK_RC(nRetVal, "Find player"); 8. 9. LOG_D("PlaybackSpeed: %d", player.GetPlaybackSpeed()); 10. 11. xn:NodeInfoList nodeList; 12. player.EnumerateNodes(nodeList); 13. for( xn::NodeInfoList::Iterator it = nodeList.Begin(); 14. it != nodeList.End(); ++it){ 15. 16. if( (*it).GetDescription().Type == XN_NODE_TYPE_IMAGE ){ 17. nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_IMAGE, g_ImageGenerator); 18. CHECK_RC(nRetVal, "Find image node"); 19. LOG_D("%s", "ImageGenerator created."); 20. } 21. else if( (*it).GetDescription().Type == XN_NODE_TYPE_DEPTH ){ 22. nRetVal = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator); 23. CHECK_RC(nRetVal, "Find depth node"); 24. LOG_D("%s", "DepthGenerator created."); 25. } 26. else{ 27. LOG_D("%s %s %s", ::xnProductionNodeTypeToString((*it).GetDescription().Type ), 28. (*it).GetInstanceName(), 29. (*it).GetDescription().strName); 30. } 31. }
簡単に説明すると
・2行目で保存されているデータを読み込みます
・6行目でPlayerを作成します
・13行目のfor文でPlayerから取り出したノードを調べて、必要なノードからgeneratorを作成します。
これで、保存したファイルからデータを読みながらプログラムを実行することができます。
今回作成したサンプルはgithubに上げてあります。
https://github.com/sparkgene/recorder_test