int main (int argc, char * argv[]) { IplImage* camera = 0; try { // コンテキストの初期化 xn::Context context; XnStatus rc = context.InitFromXmlFile(CONFIG_XML_PATH); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // 鏡モード(反転)にする context.SetGlobalMirror(TRUE); // イメージジェネレータの作成 xn::ImageGenerator image; rc = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // デプスジェネレータの作成 xn::DepthGenerator depth; rc = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // デプスの座標をイメージに合わせる depth.GetAlternativeViewPointCap().SetViewPoint(image); // ユーザーの作成 xn::UserGenerator user; rc = context.FindExistingNode( XN_NODE_TYPE_USER, user ); if ( rc != XN_STATUS_OK ) { rc = user.Create(context); if ( rc != XN_STATUS_OK ) { throw std::runtime_error( xnGetStatusString( rc ) ); } } // ユーザー検出機能をサポートしているか確認 if (!user.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) { throw std::runtime_error("ユーザー検出をサポートしてません"); } XnCallbackHandle userCallbacks, calibrationCallbacks, poseCallbacks; XnChar pose[20] = ""; // キャリブレーションにポーズが必要 xn::SkeletonCapability skelton = user.GetSkeletonCap(); if (skelton.NeedPoseForCalibration()) { // ポーズ検出のサポートチェック if (!user.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) { throw std::runtime_error("ポーズ検出をサポートしてません"); } // キャリブレーションポーズの取得 skelton.GetCalibrationPose(pose); // ポーズ検出のコールバックを登録 xn::PoseDetectionCapability pose = user.GetPoseDetectionCap(); pose.RegisterToPoseCallbacks(&::PoseDetected, &::PoseLost, &user, poseCallbacks); } // ユーザー認識のコールバックを登録 user.RegisterUserCallbacks(&::UserDetected, &::UserLost, pose, userCallbacks); // キャリブレーションのコールバックを登録 skelton.RegisterCalibrationCallbacks(&::CalibrationStart, &::CalibrationEnd, &user, calibrationCallbacks); // ユーザートラッキングで、すべてをトラッキングする skelton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL); // ジェスチャー検出の開始 context.StartGeneratingAll(); // カメラサイズのイメージを作成(8bitのRGB) XnMapOutputMode outputMode; image.GetMapOutputMode(outputMode); camera = ::cvCreateImage(cvSize(outputMode.nXRes, outputMode.nYRes), IPL_DEPTH_8U, 3); if (!camera) { throw std::runtime_error("error : cvCreateImage"); } // 表示状態 bool isShowImage = true; bool isShowUser = true; bool isShowSkelton = true; // 描画状態 static enum State{ IDLE = 0, CIRCLE, } state[15] = { IDLE }; typedef std::vector<XnPoint3D> line; line points; CvScalar color = CV_RGB(0,0,0); typedef std::vector<CvScalar> LineColors; LineColors colors; colors.push_back(CV_RGB(255,255,255)); colors.push_back(CV_RGB(255,255,255)); colors.push_back(CV_RGB(0,0,0)); colors.push_back(CV_RGB(255,0,0)); colors.push_back(CV_RGB(0,255,0)); colors.push_back(CV_RGB(0,0,255)); colors.push_back(CV_RGB(255,255,0)); colors.push_back(CV_RGB(0,255,255)); colors.push_back(CV_RGB(255,0,255)); // メインループ while (1) { // すべてのノードの更新を待つ context.WaitAndUpdateAll(); // 画像データの取得 xn::ImageMetaData imageMD; image.GetMetaData(imageMD); // ユーザーデータの取得 xn::SceneMetaData sceneMD; user.GetUserPixels(0, sceneMD); // カメラ画像の表示 char* dest = camera->imageData; const xn::RGB24Map& rgb = imageMD.RGB24Map(); for (int y = 0; y < imageMD.YRes(); ++y) { for (int x = 0; x < imageMD.XRes(); ++x) { // ユーザー表示 XnLabel label = sceneMD(x, y); if (!isShowUser) { label = 0; } // カメラ画像の表示 XnRGB24Pixel pixel = rgb(x, y); if (!isShowImage) { pixel = xnRGB24Pixel( 255, 255, 255 ); } // 出力先に描画 dest[0] = pixel.nRed * Colors[label][0]; dest[1] = pixel.nGreen * Colors[label][1]; dest[2] = pixel.nBlue * Colors[label][2]; dest += 3; } } // スケルトンの描画 if (isShowSkelton) { XnUserID aUsers[15]; XnUInt16 nUsers = 15; user.GetUsers(aUsers, nUsers); // for (int i = 0; i < nUsers; ++i) { for (int i = 0; i < 1; ++i) { if (skelton.IsTracking(aUsers[i])) { SkeltonDrawer skeltonDrawer(camera, skelton, depth, aUsers[i]); skeltonDrawer.draw(); // 右手と右肩の距離を表示 XnSkeletonJointPosition shoulder, l_shoulder, r_hand, l_hand; skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_RIGHT_SHOULDER, shoulder); skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_RIGHT_HAND, r_hand); skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_LEFT_SHOULDER, l_shoulder); skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_LEFT_HAND, l_hand); // 現実の座標を画面座標に変換する XnPoint3D pt_r_hand, pt_l_hand; depth.ConvertRealWorldToProjective(1, &r_hand.position, &pt_r_hand); depth.ConvertRealWorldToProjective(1, &l_hand.position, &pt_l_hand); // 右肩と右手の間隔が40cm以上(手を前に出してる感じ) if ((shoulder.position.Z - r_hand.position.Z) >= 400) { std::cout << " CIRCLE"; state[i] = CIRCLE; } // 右肩と右手の間隔が40cm以上(手を前に出してる感じ) if ((l_shoulder.position.Z - l_hand.position.Z) >= 400) { std::cout << " IDLE"; state[i] = IDLE; } // 左上に左手を持ってたら色を変える int r = 50; for (int c = 0; c < colors.size(); ++c) { cvRectangle(camera, cvPoint(c * r, 0), cvPoint((c+1)*r, r), colors[c], CV_FILLED); } if (pt_l_hand.Y < r) { int index = pt_l_hand.X / r; if (index == 0) { points.clear(); } else if (index < colors.size()) { std::cout << " change color"; color = colors[index]; } } std::cout << std::endl; if (state[i] == CIRCLE) { points.push_back(pt_r_hand); cvCircle(camera, cvPoint(pt_r_hand.X, pt_r_hand.Y), 10, CV_RGB(255, 255, 0), 5); } // 線を書く for (line::iterator it = points.begin();it != points.end();){ CvPoint pt1 = cvPoint(it->X, it->Y); CvPoint pt2 = cvPoint(it->X, it->Y); if (++it != points.end()) { pt2 = cvPoint(it->X, it->Y); } ::cvLine(camera, pt1, pt2, color, 3); } } } } ::cvCvtColor(camera, camera, CV_BGR2RGB); ::cvShowImage("KinectImage", camera); // キーイベント char key = cvWaitKey(10); // 終了する if (key == 'q') { break; } // 反転する else if (key == 'm') { context.SetGlobalMirror(!context.GetGlobalMirror()); } // 表示する/しないの切り替え else if (key == 'i') { isShowImage = !isShowImage; } else if (key == 'u') { isShowUser = !isShowUser; } else if (key == 's') { isShowSkelton = !isShowSkelton; } } } catch (std::exception& ex) { std::cout << ex.what() << std::endl; } ::cvReleaseImage(&camera); return 0; }
int main (int argc, char * argv[]) { try { // コンテキストの初期化 xn::Context context; XnStatus rc = context.InitFromXmlFile(CONFIG_XML_PATH); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // イメージジェネレータの作成 xn::ImageGenerator image; rc = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // デプスジェネレータの作成 xn::DepthGenerator depth; rc = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth); if (rc != XN_STATUS_OK) { throw std::runtime_error(xnGetStatusString(rc)); } // デプスの座標をイメージに合わせる depth.GetAlternativeViewPointCap().SetViewPoint(image); // ユーザーの作成 xn::UserGenerator user; rc = context.FindExistingNode( XN_NODE_TYPE_USER, user ); if ( rc != XN_STATUS_OK ) { rc = user.Create(context); if ( rc != XN_STATUS_OK ) { throw std::runtime_error( xnGetStatusString( rc ) ); } } // ユーザー検出機能をサポートしているか確認 if (!user.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) { throw std::runtime_error("ユーザー検出をサポートしてません"); } XnCallbackHandle userCallbacks, calibrationCallbacks, poseCallbacks; XnChar pose[20] = ""; // キャリブレーションにポーズが必要 xn::SkeletonCapability skelton = user.GetSkeletonCap(); if (skelton.NeedPoseForCalibration()) { // ポーズ検出のサポートチェック if (!user.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) { throw std::runtime_error("ポーズ検出をサポートしてません"); } // キャリブレーションポーズの取得 skelton.GetCalibrationPose(pose); // ポーズ検出のコールバックを登録 xn::PoseDetectionCapability pose = user.GetPoseDetectionCap(); pose.RegisterToPoseCallbacks(&::PoseDetected, &::PoseLost, &user, poseCallbacks); } // ユーザー認識のコールバックを登録 user.RegisterUserCallbacks(&::UserDetected, &::UserLost, pose, userCallbacks); // キャリブレーションのコールバックを登録 skelton.RegisterCalibrationCallbacks(&::CalibrationStart, &::CalibrationEnd, &user, calibrationCallbacks); // ユーザートラッキングで、すべてをトラッキングする skelton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL); // ジェスチャー検出の開始 context.StartGeneratingAll(); // カメラサイズのイメージを作成(8bitのRGB) XnMapOutputMode outputMode; image.GetMapOutputMode(outputMode); cv::Ptr< IplImage > camera = ::cvCreateImage(cvSize(outputMode.nXRes, outputMode.nYRes), IPL_DEPTH_8U, 3); if (!camera) { throw std::runtime_error("error : cvCreateImage"); } // メインループ while (1) { // すべてのノードの更新を待つ context.WaitAndUpdateAll(); // 画像データの取得 xn::ImageMetaData imageMD; image.GetMetaData(imageMD); // ユーザーデータの取得 xn::SceneMetaData sceneMD; user.GetUserPixels(0, sceneMD); // カメラ画像の表示 char* dest = camera->imageData; const xn::RGB24Map& rgb = imageMD.RGB24Map(); for (int y = 0; y < imageMD.YRes(); ++y) { for (int x = 0; x < imageMD.XRes(); ++x) { // ユーザー表示 XnLabel label = sceneMD(x, y); // カメラ画像の表示 XnRGB24Pixel pixel = rgb(x, y); pixel = xnRGB24Pixel( 255, 255, 255 ); // 出力先に描画 dest[0] = pixel.nRed * Colors[label][0]; dest[1] = pixel.nGreen * Colors[label][1]; dest[2] = pixel.nBlue * Colors[label][2]; dest += 3; } } // スケルトンの描画 XnUserID aUsers[15]; XnUInt16 nUsers = 15; user.GetUsers(aUsers, nUsers); for (int i = 0; i < nUsers; ++i) { if (skelton.IsTracking(aUsers[i])) { SkeltonDrawer skeltonDrawer(camera, skelton, depth, aUsers[i]); skeltonDrawer.draw(); } } ::cvCvtColor(camera, camera, CV_BGR2RGB); ::cvShowImage("KinectImage", camera); // キーイベント char key = cvWaitKey(10); // 終了する if (key == 'q') { break; } } } catch (std::exception& ex) { std::cout << ex.what() << std::endl; } return 0; }