// スケルトンを描画する void DrawSkelton(XnUserID player, int idx){ // 線を引く開始と終了のJointの定義 XnSkeletonJoint joints[][2] = { {XN_SKEL_HEAD, XN_SKEL_NECK}, {XN_SKEL_NECK, XN_SKEL_LEFT_SHOULDER}, {XN_SKEL_LEFT_SHOULDER, XN_SKEL_LEFT_ELBOW}, {XN_SKEL_LEFT_ELBOW, XN_SKEL_LEFT_HAND}, {XN_SKEL_NECK, XN_SKEL_RIGHT_SHOULDER}, {XN_SKEL_RIGHT_SHOULDER, XN_SKEL_RIGHT_ELBOW}, {XN_SKEL_RIGHT_ELBOW, XN_SKEL_RIGHT_HAND}, {XN_SKEL_LEFT_SHOULDER, XN_SKEL_TORSO}, {XN_SKEL_RIGHT_SHOULDER, XN_SKEL_TORSO}, {XN_SKEL_TORSO, XN_SKEL_LEFT_HIP}, {XN_SKEL_LEFT_HIP, XN_SKEL_LEFT_KNEE}, {XN_SKEL_LEFT_KNEE, XN_SKEL_LEFT_FOOT}, {XN_SKEL_TORSO, XN_SKEL_RIGHT_HIP}, {XN_SKEL_RIGHT_HIP, XN_SKEL_RIGHT_KNEE}, {XN_SKEL_RIGHT_KNEE, XN_SKEL_RIGHT_FOOT}, {XN_SKEL_LEFT_HIP, XN_SKEL_RIGHT_HIP} }; XnSkeletonJointPosition joint1, joint2; int nJointsCount = sizeof(joints) / sizeof(joints[0]); int color_idx = idx; if( color_idx > (sizeof(g_Colors) / sizeof(g_Colors[0])) ){ color_idx = (sizeof(g_Colors) / sizeof(g_Colors[0])) - 1; } for(int i = 0; i < nJointsCount;i++){ g_SkeletonCap.GetSkeletonJointPosition(player, joints[i][0], joint1); g_SkeletonCap.GetSkeletonJointPosition(player, joints[i][1], joint2); if (joint1.fConfidence < 0.2 || joint2.fConfidence < 0.2){ return; } XnPoint3D pt[2]; pt[0] = joint1.position; pt[1] = joint2.position; g_DepthGenerator.ConvertRealWorldToProjective(2, pt, pt); // 線で結んで cvLine( g_rgbImage, cvPoint(pt[0].X, pt[0].Y), cvPoint(pt[1].X, pt[1].Y), g_Colors[color_idx], 1, CV_AA); // それぞれの点を塗りつぶす cvCircle(g_rgbImage, cvPoint(pt[0].X, pt[0].Y), 2, g_Colors[color_idx], -1, CV_AA, 0); cvCircle(g_rgbImage, cvPoint(pt[1].X, pt[1].Y), 2, g_Colors[color_idx], -1, CV_AA, 0); } }
/** * Body に画像をコラージュ */ void drawBodyPreLoad(xn::DepthGenerator& depth, xn::SkeletonCapability& capability, XnSkeletonJoint joint, XnUserID user, XnMapOutputMode mapMode, IplImage* preLoadImage, IplImage **rgbImage) { XnSkeletonJointPosition pos; IplImage *partImage = NULL; IplImage *fallImage = NULL; // ジョイント座標の取得 capability.GetSkeletonJointPosition(user, joint, pos); XnPoint3D pReal[1] = {pos.position}; XnPoint3D pProjective[1]; // 世界座標系から表示座標系に変換した座標を取得 depth.ConvertRealWorldToProjective(1, pReal, pProjective); // 重ね合わせよう画像 partImage = preLoadImage; fallImage = cvCreateImage(cvSize(mapMode.nXRes, mapMode.nYRes), IPL_DEPTH_8U, 3); CvPoint2D32f original[3]; CvPoint2D32f transform[3]; original[0] = cvPoint2D32f(0, 0); original[1] = cvPoint2D32f(mapMode.nXRes, 0); original[2] = cvPoint2D32f( 0, mapMode.nYRes); CvSize sizeOfPart = cvGetSize(partImage); int transX = pProjective[0].X - (sizeOfPart.width / 2); int transY = pProjective[0].Y - (sizeOfPart.height / 2); transform[0] = cvPoint2D32f( transX, transY); transform[1] = cvPoint2D32f( transX + mapMode.nXRes, transY); transform[2] = cvPoint2D32f( transX , transY + mapMode.nYRes); // 行列作成 CvMat *affineMatrix = cvCreateMat(2, 3, CV_32FC1); cvGetAffineTransform(original, transform, affineMatrix); // 移動 cvWarpAffine(partImage, fallImage, affineMatrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0)); // 画像の重ね合わせ fallPartImage(fallImage, *rgbImage); // 解放 cvReleaseImage(&fallImage); //cvReleaseImage(&partImage); }
//左上腕(LEFT_ELBOW - LEFT_SHOULDER)に画像をコラージュ void drawLeftArm(xn::DepthGenerator& depth, xn::SkeletonCapability& capability, XnUserID user, XnMapOutputMode mapMode, IplImage* preLoadImage, IplImage **rgbImage) { XnSkeletonJointPosition pos1,pos2; IplImage *partImage = NULL; IplImage *fallImage = NULL; // elbowのジョイント座標の取得 capability.GetSkeletonJointPosition(user, XN_SKEL_LEFT_ELBOW, pos1); XnPoint3D pReal1[1] = {pos1.position}; XnPoint3D pProjective1[1]; // 世界座標系から表示座標系に変換した座標を取得 depth.ConvertRealWorldToProjective(1, pReal1, pProjective1); // sholderのジョイント座標の取得 capability.GetSkeletonJointPosition(user, XN_SKEL_LEFT_SHOULDER, pos2); XnPoint3D pReal2[1] = {pos2.position}; XnPoint3D pProjective2[1]; // 世界座標系から表示座標系に変換した座標を取得 depth.ConvertRealWorldToProjective(1, pReal2, pProjective2); // 重ね合わせよう画像 partImage = preLoadImage; fallImage = cvCreateImage(cvSize(mapMode.nXRes, mapMode.nYRes), IPL_DEPTH_8U, 3); CvPoint2D32f original[3]; CvPoint2D32f transform[3]; original[0] = cvPoint2D32f(0, 0); original[1] = cvPoint2D32f(mapMode.nXRes, 0); original[2] = cvPoint2D32f( 0, mapMode.nYRes); CvSize sizeOfPart = cvGetSize(partImage); //ELBOWの位置 int transX1 = pProjective1[0].X; int transY1 = pProjective1[0].Y; //SHOULDERの位置 int transX2 = pProjective2[0].X; int transY2 = pProjective2[0].Y; //中間の座標 int transX3 = (transX1 + transX2) / 2; int transY3 = (transY1 + transY2) / 2; //画像の始点 int transX = transX3 - (sizeOfPart.width / 2); int transY = transY3 - (sizeOfPart.height / 2); //角度 float ang = cvFastArctan(transY2 - transY1, transX2 - transX1); //+ cvFastArctan(transY1, transX1); transform[0] = cvPoint2D32f( transX, transY); transform[1] = cvPoint2D32f( transX + mapMode.nXRes, transY); transform[2] = cvPoint2D32f( transX, transY + mapMode.nYRes); // 行列作成 CvMat *affineMatrix = cvCreateMat(2, 3, CV_32FC1); cvGetAffineTransform(original, transform, affineMatrix); // 移動 cvWarpAffine(partImage, fallImage, affineMatrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0)); //回転行列作成 CvPoint2D32f center = cvPoint2D32f(transX3, transY3); IplImage *fallImage2 = cvCreateImage(cvSize(mapMode.nXRes, mapMode.nYRes), IPL_DEPTH_8U, 3); CvMat *rotationMatrix = cvCreateMat(2, 3, CV_32FC1); cv2DRotationMatrix(center, 90.0 - ang, 1.0, rotationMatrix); //回転 cvWarpAffine(fallImage, fallImage2, rotationMatrix, CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, cvScalarAll(0)); // 画像の重ね合わせ fallPartImage(fallImage2, *rgbImage); // 解放 cvReleaseImage(&fallImage); cvReleaseImage(&fallImage2); }