private void RecogMove(PXCMHandData.IHand hand, PXCMPointF32 mcp) { int side = (int)hand.QueryBodySide() - 1; if (side < 0) { return; } hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_MIDDLE_TIP, out middleData[side]); if (oldMiddleData[side] == null) { oldMiddleData[side] = middleData[side]; return; } //Console.WriteLine(middleData[side].speed.x); var distance = Math.Pow( Math.Pow(middleData[side].positionWorld.x - oldMiddleData[side].positionWorld.x, 2) + Math.Pow(middleData[side].positionWorld.y - oldMiddleData[side].positionWorld.y, 2) + Math.Pow((middleData[side].positionWorld.z - oldMiddleData[side].positionWorld.z) * 1000, 2), 0.5); oldMiddleData[side] = middleData[side]; //Console.Write(middleData[side].positionImage.x + ":" + oldMiddleData[side].positionImage.x + ":"); //Console.WriteLine(middleData[side].positionImage.x - oldMiddleData[side].positionImage.x); //oldMiddleData = middleData; }
public void ProcessingThread() { // Start AcquireFrame/ReleaseFrame loop while (senseManager.AcquireFrame(true) >= pxcmStatus.PXCM_STATUS_NO_ERROR) { hand = senseManager.QueryHand(); if (hand != null) { // Retrieve the most recent processed data handData = hand.CreateOutput(); handData.Update(); // Get number of tracked hands nhands = handData.QueryNumberOfHands(); if (nhands > 0) { // Retrieve hand identifier handData.QueryHandId(PXCMHandData.AccessOrderType.ACCESS_ORDER_BY_TIME, 0, out handId); // Retrieve hand data handData.QueryHandDataById(handId, out ihand); PXCMHandData.BodySideType bodySideType = ihand.QueryBodySide(); if (bodySideType == PXCMHandData.BodySideType.BODY_SIDE_LEFT) { leftHand = true; } else if (bodySideType == PXCMHandData.BodySideType.BODY_SIDE_RIGHT) { leftHand = false; } // Retrieve all hand joint data for (int i = 0; i < nhands; i++) { for (int j = 0; j < 0x20; j++) { PXCMHandData.JointData jointData; ihand.QueryTrackedJoint((PXCMHandData.JointType)j, out jointData); nodes[i][j] = jointData; } } // Get world coordinates for tip of middle finger on the first hand in camera range handTipX = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionWorld.x; handTipY = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionWorld.y; handTipZ = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionWorld.z; swipehandTipX = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionImage.x; swipehandTipY = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionImage.y; swipehandTipZ = nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].positionImage.z; //Console.Out.WriteLine("Before x={0}", swipehandTipX); //Console.Out.WriteLine("Before speed={0}", nodes[0][Convert.ToInt32(PXCMHandData.JointType.JOINT_MIDDLE_TIP)].speed.x); // Retrieve gesture data if (handData.IsGestureFired("spreadfingers", out gestureData)) { gesture = Gesture.FingerSpread; } else if (handData.IsGestureFired("two_fingers_pinch_open", out gestureData)) { gesture = Gesture.Pinch; } else if (handData.IsGestureFired("wave", out gestureData)) { gesture = Gesture.Wave; } else if (handData.IsGestureFired("swipe_left", out gestureData)) { gesture = Gesture.SwipeLeft; } else if (handData.IsGestureFired("swipe_right", out gestureData)) { gesture = Gesture.SwipeRight; } else if (handData.IsGestureFired("fist", out gestureData)) { gesture = Gesture.Fist; } else if (handData.IsGestureFired("thumb_up", out gestureData)) { gesture = Gesture.Thumb; } } else { gesture = Gesture.Undefined; } UpdateUI(); if (handData != null) { handData.Dispose(); } } senseManager.ReleaseFrame(); } }
private void DetectTap(PXCMHandData.IHand hand) { PXCMHandData.JointData MiddleData; PXCMHandData.JointData CenterData; //指のデータをとってくる(depth) //ユーザの右手のデータ if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_LEFT) { hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_CENTER, out CenterData); RightCenter = CenterData.positionWorld; hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_MIDDLE_TIP, out MiddleData); RightMiddle = MiddleData.positionWorld; //RightCenter = hand.QueryMassCenterWorld(); } //ユーザの左手のデータ if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_RIGHT) { hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_CENTER, out CenterData); LeftCenter = CenterData.positionWorld; hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_MIDDLE_TIP, out MiddleData); LeftMiddle = MiddleData.positionWorld; } //if文の条件を記述(前の指のデータと比較) // ユーザの右手でタップ if (-RightMiddle.z + preRightMiddle.z > 0.02 && // 1F(約1/60秒)あたりの深度の変化が0.02m以上 System.Math.Pow(System.Math.Pow(RightMiddle.x - preRightMiddle.x, 2) // 指先の速度が1.8m/s以上 + System.Math.Pow(RightMiddle.y - preRightMiddle.y, 2) + System.Math.Pow(RightMiddle.z * 1000 - preRightMiddle.z * 1000, 2), 0.5) > 0.03 && System.Math.Pow(System.Math.Pow(RightCenter.x - preRightCenter.x, 2) // 手のひらの速度が0.6m/s以上 + System.Math.Pow(RightCenter.y - preRightCenter.y, 2) + System.Math.Pow(RightCenter.z * 1000 - preRightCenter.z * 1000, 2), 0.5) > 0.01 && rsw.ElapsedMilliseconds > 250 ) { //tap音を出力 midiManager.SetOnNote(player.MusicTime); rsw.Restart(); } // ユーザの左手でタップ if (-LeftMiddle.z + preLeftMiddle.z > 0.02 && // 1F(約1/60秒)あたりの深度の変化が0.02m以上 System.Math.Pow(System.Math.Pow(LeftMiddle.x - preLeftMiddle.x, 2) // 指先の速度が1.8m/s以上 + System.Math.Pow(RightMiddle.y - preLeftMiddle.y, 2) + System.Math.Pow(RightMiddle.z - preLeftMiddle.z, 2), 0.5) > 0.03 && System.Math.Pow(System.Math.Pow(RightCenter.x - preLeftCenter.x, 2) // 手のひらの速度が0.6m/s以上 + System.Math.Pow(RightCenter.y - preLeftCenter.y, 2) + System.Math.Pow(RightCenter.z - preLeftCenter.z, 2), 0.5) > 0.01 && System.Math.Pow(System.Math.Pow(RightCenter.x - preLeftCenter.x, 2) // 手のひらの速度が1.5m/s以下 + System.Math.Pow(RightCenter.y - preLeftCenter.y, 2) + System.Math.Pow(RightCenter.z - preLeftCenter.z, 2), 0.5) < 0.025 ) { //tap音を出力 midiManager.SetOnNote(player.MusicTime); } //Console.WriteLine("RightCenter.x:" + RightCenter.x); //Console.WriteLine("preRightCenter.x:" + preRightCenter.x); //Console.WriteLine(); //Console.WriteLine("RightMiddle.x:" + RightMiddle.x); //Console.WriteLine("preRightMiddle.x:" + preRightMiddle.x); //前の指のデータに今の指のデータを上書き //plc,preLeftMiddle,preRightCenter,preRightMiddle // 上手くいかなければディープコピーする. preRightCenter.x = RightCenter.x; preRightCenter.y = RightCenter.y; preRightCenter.z = RightCenter.z; preRightMiddle.x = RightMiddle.x; preRightMiddle.y = RightMiddle.y; preRightMiddle.z = RightMiddle.z; preLeftCenter.x = LeftCenter.x; preLeftCenter.y = LeftCenter.y; preLeftCenter.z = LeftCenter.z; preLeftMiddle.x = LeftMiddle.x; preLeftMiddle.y = LeftMiddle.y; preLeftMiddle.z = LeftMiddle.z; }
private void DetectTap(PXCMHandData.IHand hand, PXCMPointF32 mcp) { PXCMHandData.JointData midData; PXCMHandData.JointData cntData; //指のデータをとってくる(depth) //ユーザの右手のデータ if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_LEFT) { hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_CENTER, out cntData); RightCenter = cntData.positionWorld; hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_MIDDLE_TIP, out midData); RightMiddle = midData.positionWorld; } //ユーザの左手のデータ if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_RIGHT) { hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_CENTER, out cntData); LeftCenter = cntData.positionWorld; hand.QueryTrackedJoint(PXCMHandData.JointType.JOINT_MIDDLE_TIP, out midData); LeftMiddle = midData.positionWorld; } if (mcp.y < 0) { mcp.y = 0; } if (mcp.y > ColorImage.Height) { mcp.y = (float)ColorImage.Height; } //Console.WriteLine(rsw.ElapsedMilliseconds); //if文の条件を記述(前の指のデータと比較) // ユーザの右手でタップ if (-RightMiddle.z + preRightMiddle.z > 0.02 && // 1F(約1/60秒)あたりの深度の変化が0.02m以上 Math.Pow(Math.Pow(RightMiddle.x - preRightMiddle.x, 2) // 指先の速度が1.8m/s以上 + Math.Pow(RightMiddle.y - preRightMiddle.y, 2) + Math.Pow(RightMiddle.z * 1000 - preRightMiddle.z * 1000, 2), 0.5) > 0.03 && Math.Pow(Math.Pow(RightCenter.x - preRightCenter.x, 2) // 手のひらの速度が0.6m/s以上 + Math.Pow(RightCenter.y - preRightCenter.y, 2) + Math.Pow(RightCenter.z * 1000 - preRightCenter.z * 1000, 2), 0.5) > 0.01 && rsw.ElapsedMilliseconds > 300 ) { //tap音を出力 midi.OnNote(currentFreqs[(int)(((ColorImage.Height - mcp.y) / (ColorImage.Height + 0.01)) * currentFreqs.Length)]); rsw.Restart(); } //var c = ColorImage.Height - y; //var e = c / ColorImage.Height; //var d = e * currentFreqs.Length; //Index.Text = y + "\n" + d + "\n" + (int)d; //Index.Text = mcp.y.ToString(); //Chord.Text = e.ToString(); // ユーザの左手でタップ if (-LeftMiddle.z + preLeftMiddle.z > 0.02 && // 1F(約1/60秒)あたりの深度の変化が0.02m以上 Math.Pow(Math.Pow(LeftMiddle.x - preLeftMiddle.x, 2) // 指先の速度が1.8m/s以上 + Math.Pow(LeftMiddle.y - preLeftMiddle.y, 2) + Math.Pow(LeftMiddle.z * 1000 - preLeftMiddle.z * 1000, 2), 0.5) > 0.03 && Math.Pow(Math.Pow(LeftCenter.x - preLeftCenter.x, 2) // 手のひらの速度が0.6m/s以上 + Math.Pow(LeftCenter.y - preLeftCenter.y, 2) + Math.Pow(LeftCenter.z * 1000 - preLeftCenter.z * 1000, 2), 0.5) > 0.01 && lsw.ElapsedMilliseconds > 300 ) { //tap音を出力 //midi.OnNote(currentFreqs[(int)(((ColorImage.Height - mcp.y) / (ColorImage.Height + 0.01)) * currentFreqs.Length)]); lsw.Restart(); } //Console.WriteLine("RightCenter.x:" + RightCenter.x); //Console.WriteLine("preRightCenter.x:" + preRightCenter.x); //Console.WriteLine(); //Console.WriteLine("RightMiddle.x:" + RightMiddle.x); //Console.WriteLine("preRightMiddle.x:" + preRightMiddle.x); //前の指のデータに今の指のデータを上書き //plc,preLeftMiddle,preRightCenter,preRightMiddle // 上手くいかなければディープコピーする. preRightCenter.x = RightCenter.x; preRightCenter.y = RightCenter.y; preRightCenter.z = RightCenter.z; preRightMiddle.x = RightMiddle.x; preRightMiddle.y = RightMiddle.y; preRightMiddle.z = RightMiddle.z; preLeftCenter.x = LeftCenter.x; preLeftCenter.y = LeftCenter.y; preLeftCenter.z = LeftCenter.z; preLeftMiddle.x = LeftMiddle.x; preLeftMiddle.y = LeftMiddle.y; preLeftMiddle.z = LeftMiddle.z; }
/// <summary> 指のデータを取得する </summary> private bool GetFingerData(PXCMHandData.IHand hand, PXCMHandData.JointType jointType) { PXCMHandData.JointData jointData; var sts = hand.QueryTrackedJoint(jointType, out jointData); if (sts < pxcmStatus.PXCM_STATUS_NO_ERROR) { return(false); } // Depth座標系をカラー座標系に変換する var depthPoint = new PXCMPoint3DF32[1]; var colorPoint = new PXCMPointF32[1]; depthPoint[0].x = jointData.positionImage.x; depthPoint[0].y = jointData.positionImage.y; depthPoint[0].z = jointData.positionWorld.z * 1000; projection.MapDepthToColor(depthPoint, colorPoint); var masp = hand.QueryMassCenterImage(); var mdp = new PXCMPoint3DF32[1]; var mcp = new PXCMPointF32[1]; mdp[0].x = masp.x; mdp[0].y = masp.y; mdp[0].z = hand.QueryMassCenterWorld().z * 1000; projection.MapDepthToColor(mdp, mcp); //Console.WriteLine(mcp[0].x); AddEllipse(new Point(mcp[0].x, mcp[0].y), 10, Brushes.Red, 1); colorPoint = mcp; //ユーザの右手に対して演奏領域の当たり判定確認 if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_LEFT) { for (int i = 0; i < 5; i++) { if ((imageColor.Height / 5) * i <= colorPoint[0].y && colorPoint[0].y < (imageColor.Height / 5) * (i + 1)) { if (16 - i != NowRange) { NowRange = 16 - i; PivotList.Dispatcher.BeginInvoke( new Action(() => { PivotList.SelectedItem = NowRange; } )); } } } } //ユーザの左手に対してアイコンの当たり判定の確認 if (hand.QueryBodySide() == PXCMHandData.BodySideType.BODY_SIDE_RIGHT) { IconHitCheck(colorPoint[0]); } AddEllipse(new Point(colorPoint[0].x, colorPoint[0].y), 5, Brushes.White, 1); return(true); }