/// <summary> ///点击暂停计时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void Timer_Tick(object sender, EventArgs e) { if (!doClick || useGripGesture) { return; } if (!alreadyTrackedPos) { timeCount = 0; return; } Point curPos = MouseControl.GetCursorPosition(); //光标落在按钮范围内 if ((lastCurPos - curPos).Length < pauseThresold) {//并且停留时间大于设置时间,实现点击事件 if ((timeCount += 0.1f) > timeRequired) { //MouseControl.MouseLeftDown(); //MouseControl.MouseLeftUp(); MouseControl.DoMouseClick(); timeCount = 0; } } else { timeCount = 0; } lastCurPos = curPos; }
/// Pause to click timer void Timer_Tick(object sender, EventArgs e) { if (!doClick || useGripGesture) { return; } if (!alreadyTrackedPos) { timeCount = 0; return; } Point curPos = MouseControl.GetCursorPosition(); if (((lastCurPos - curPos).Length < pauseThresold) && ((timeCount += 0.1f) > timeRequired)) { MouseControl.DoMouseClick(); timeCount = 0; } else { timeCount = 0; } lastCurPos = curPos; }
/// this function is used to set the cursor relative to the left/right hand position towards the screen private void setcursor(float x, float y, Body body, int hand) { Point curPos = MouseControl.GetCursorPosition(); // smoothing for using should be 0 - 0.95f. The way we smooth the cusor is: oldPos + (newPos - oldPos) * smoothValue float smoothing = 1 - cursorSmoothing; // set cursor position int cursor_x = (int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing); int cursor_y = (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing); MouseControl.SetCursorPos(cursor_x, cursor_y); alreadyTrackedPos = true; // Grip gesture /// the following is used to click if (doClick && useGripGesture) { if ((body.HandRightState == HandState.Closed || (body.HandLeftState == HandState.Closed)) && !wasLRGrip) { MouseControl.MouseLeftDown(); wasLRGrip = true; } else if ((body.HandRightState == HandState.Open || body.HandRightState == HandState.Lasso || body.HandLeftState == HandState.Open || body.HandLeftState == HandState.Lasso) && wasLRGrip) { MouseControl.MouseLeftUp(); wasLRGrip = false; } } }
private static void move(float mouseSensitivity) { float x = nowHand.selectHand.X - nowHand.spineBase.X + 0.05f; float y = nowHand.spineBase.Y - nowHand.selectHand.Y + 0.51f; // get current cursor position Point curPos = MouseControl.GetCursorPosition(); // smoothing for using should be 0 - 0.95f. The way we smooth the cusor is: oldPos + (newPos - oldPos) * smoothValue float smoothing = 1 - cursorSmoothing; // set cursor position MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); }
/// <summary> ///阅读的身体框架 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void bodyFrameReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e) { bool dataReceived = false; //获取一帧身体数据 using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame()) { if (bodyFrame != null) { if (this.bodies == null) { this.bodies = new Body[bodyFrame.BodyCount]; } //第一次GetAndRefreshBodyData被调用时,Kinect将在数组中分配每个主体。 //只要这些物体不被处理,并且在数组中不被设置为空, //这些物体将被重新使用。 bodyFrame.GetAndRefreshBodyData(this.bodies); dataReceived = true; } } if (!dataReceived) { alreadyTrackedPos = false; return; } foreach (Body body in this.bodies) { //第一个被跟踪的身体,注意下面有一个休息。 if (body.IsTracked) { // 得到各种骨骼位置 CameraSpacePoint handLeft = body.Joints[JointType.HandLeft].Position; CameraSpacePoint handRight = body.Joints[JointType.HandRight].Position; CameraSpacePoint spineBase = body.Joints[JointType.SpineBase].Position; // 如果右手向前推进 if (handRight.Z - spineBase.Z < -0.15f) { //用这个计算的手x。我们不使用右肩作为参考, //因为肩膀的右肩通常是在升力的后面,而这个位置是推断和不稳定的。 //因为脊椎底部在右手的左边,我们加上0.05f,使它更接近右边。 float x = handRight.X - spineBase.X + 0.05f; //用这个来计算。它的脊柱底部比右方要低,我们加上0.51f来让它成为higer, //值0.51是通过多次测试来计算的,你可以把它设置为你喜欢的另一个。 float y = spineBase.Y - handRight.Y + 0.51f; // 得到当前光标位置 Point curPos = MouseControl.GetCursorPosition(); //使用的平滑度应该是0-0.95f。我们的算法是:oldPos + (newPos - oldPos) * smoothValue float smoothing = 1 - cursorSmoothing; // 设置光标位置 MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); alreadyTrackedPos = true; //控制动作 if (doClick && useGripGesture) {//用握拳动作进行完成点击事件 ///////////////////////添加缩放功能///////////////////////////// bool isZoom = (System.Math.Abs(handRight.Z - body.Joints[JointType.ShoulderRight].Position.Z) > 0.5); if (body.HandRightState == HandState.Open && isZoom) { MouseControl.MouseAmplification(); System.Threading.Thread.Sleep(200); } else if (body.HandRightState == HandState.Closed && isZoom) { MouseControl.MouseNarrow(); System.Threading.Thread.Sleep(200); } //////////////////////////////////////////////////// if (body.HandRightState == HandState.Closed && !isZoom) { if (!wasRightGrip) { MouseControl.MouseLeftDown(); wasRightGrip = true; } } else if (body.HandRightState == HandState.Open && !isZoom) { if (wasRightGrip) { MouseControl.MouseLeftUp(); wasRightGrip = false; } } } } //////////////////实现双手识别/////////////////////////////////////////////// //else if (handLeft.Z - spineBase.Z < -0.15f) // if left hand lift forward //{ // float x = handLeft.X - spineBase.X + 0.3f; // float y = spineBase.Y - handLeft.Y + 0.51f; // Point curPos = MouseControl.GetCursorPosition(); // float smoothing = 1 - cursorSmoothing; // MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); // alreadyTrackedPos = true; // if (doClick && useGripGesture) // { // if (body.HandLeftState == HandState.Closed) // { // if (!wasLeftGrip) // { // MouseControl.MouseLeftDown(); // wasLeftGrip = true; // } // } // else if (body.HandLeftState == HandState.Open) // { // if (wasLeftGrip) // { // MouseControl.MouseLeftUp(); // wasLeftGrip = false; // } // } // } //} else { wasLeftGrip = true; wasRightGrip = true; alreadyTrackedPos = false; } // 第一个被跟踪的身体 break; } } }
/// <summary> /// Read body frames /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void bodyFrameReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e) { bool dataReceived = false; using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame()) { if (bodyFrame != null) { if (this.bodies == null) { this.bodies = new Body[bodyFrame.BodyCount]; } // The first time GetAndRefreshBodyData is called, Kinect will allocate each Body in the array. // As long as those body objects are not disposed and not set to null in the array, // those body objects will be re-used. bodyFrame.GetAndRefreshBodyData(this.bodies); dataReceived = true; } } if (!dataReceived) { alreadyTrackedPos = false; return; } foreach (Body body in this.bodies) { // get first tracked body only, notice there's a break below. if (body.IsTracked) { // get various skeletal positions CameraSpacePoint handLeft = body.Joints[JointType.HandLeft].Position; CameraSpacePoint handRight = body.Joints[JointType.HandRight].Position; CameraSpacePoint spineBase = body.Joints[JointType.SpineBase].Position; if (handRight.Z - spineBase.Z < -0.15f) // if right hand lift forward { /* hand x calculated by this. we don't use shoulder right as a reference cause the shoulder right * is usually behind the lift right hand, and the position would be inferred and unstable. * because the spine base is on the left of right hand, we plus 0.05f to make it closer to the right. */ float x = handRight.X - spineBase.X + 0.05f; /* hand y calculated by this. ss spine base is way lower than right hand, we plus 0.51f to make it * higer, the value 0.51f is worked out by testing for a several times, you can set it as another one you like. */ float y = spineBase.Y - handRight.Y + 0.51f; // get current cursor position Point curPos = MouseControl.GetCursorPosition(); // smoothing for using should be 0 - 0.95f. The way we smooth the cusor is: oldPos + (newPos - oldPos) * smoothValue float smoothing = 1 - cursorSmoothing; // set cursor position MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); alreadyTrackedPos = true; // Grip gesture if (doClick && useGripGesture) { if (body.HandRightState == HandState.Closed) { if (!wasRightGrip) { MouseControl.MouseLeftDown(); wasRightGrip = true; } } else if (body.HandRightState == HandState.Open) { if (wasRightGrip) { MouseControl.MouseLeftUp(); wasRightGrip = false; } } } } else if (handLeft.Z - spineBase.Z < -0.15f) // if left hand lift forward { float x = handLeft.X - spineBase.X + 0.3f; float y = spineBase.Y - handLeft.Y + 0.51f; Point curPos = MouseControl.GetCursorPosition(); float smoothing = 1 - cursorSmoothing; MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); alreadyTrackedPos = true; if (doClick && useGripGesture) { if (body.HandLeftState == HandState.Closed) { if (!wasLeftGrip) { MouseControl.MouseLeftDown(); wasLeftGrip = true; } } else if (body.HandLeftState == HandState.Open) { if (wasLeftGrip) { MouseControl.MouseLeftUp(); wasLeftGrip = false; } } } } else { wasLeftGrip = true; wasRightGrip = true; alreadyTrackedPos = false; } // get first tracked body only break; } } }
/// <summary> /// Read body frames /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void bodyFrameReader_FrameArrived(object sender, BodyFrameArrivedEventArgs e) { bool dataReceived = false; using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame()) { if (bodyFrame != null) { if (this.bodies == null) { this.bodies = new Body[bodyFrame.BodyCount]; } /* * // The first time GetAndRefreshBodyData is called, Kinect will allocate each Body in the array. * // As long as those body objects are not disposed and not set to null in the array, * // those body objects will be re-used. */ bodyFrame.GetAndRefreshBodyData(this.bodies); dataReceived = true; } } if (!dataReceived) { alreadyTrackedPos = false; return; } foreach (Body body in this.bodies) { // get first tracked body only, notice there's a break below. if (body.IsTracked) { // get various skeletal positions CameraSpacePoint handLeft = body.Joints[JointType.HandLeft].Position; CameraSpacePoint handRight = body.Joints[JointType.HandRight].Position; CameraSpacePoint spineBase = body.Joints[JointType.SpineBase].Position; if ((handRight.Z - spineBase.Z < -0.15f) && (handLeft.Z - spineBase.Z < -0.15f)) { //this portion (if clause) was added to add another guesture //specifically the windows magnification tool using keyboard shortcut 'windows'+'+' or 'windows'+'-' this.right_x = handRight.X - spineBase.X + 0.05f; this.right_y = handRight.Y - spineBase.Y + 0.51f; this.right_z = handRight.Z - spineBase.Z; this.left_x = handLeft.X - spineBase.X + 0.3f; this.left_y = spineBase.Y - handLeft.Y + 0.51f; this.left_z = spineBase.Z - handLeft.Z; alreadyTrackedPos = true; if (doClick && useGripGesture) { if (((body.HandRightState == HandState.Closed) && !wasRightGrip) && ((body.HandLeftState == HandState.Closed) && !wasLeftGrip)) { //when both hands are closed and are moving in and out to zoom in/out //send keyboard commands here wasRightGrip = true; wasLeftGrip = true; /* * If you look at the Joint class, you find you can get the position for that joint and that each position * has X, Y, Z coordinates. For example if you wanted to calculate the distance between both hands * (I know that's not what you want, it's an example for the sake of simplicity) * you could do: */ //Get the positions pRH = body.Joints[JointType.HandRight].Position; pLH = body.Joints[JointType.HandLeft].Position; //Some maths sqDistance = Math.Pow(pRH.X - pLH.X, 2) + Math.Pow(pRH.Y - pLH.Y, 2) + Math.Pow(pRH.Z - pLH.Z, 2); distance = Math.Sqrt(sqDistance); /* Message Box and Console output Debug for distance between hands */ string stringVal; stringVal = System.Convert.ToString(distance); System.Console.WriteLine("{0} as a string is: {1}", distance, stringVal); MessageBox.Show(string.Format("Distance from left to right is: {0}", stringVal)); /* * Think also that the Kinect programming model you choose is based on C# (and WPF or Windows Store apps). * When asking in the forum, some previous knowledge about these technologies is assumed. If you are not * familiar with this kind of framework, maybe it will be a good idea to learn a little of C# before working * with the Kinect API. */ /* * protected override bool ProcessCmdKey(ref Message msg, Keys keyData) * { * if (handRight.Z) * { * myButtonToOpenSomething.PerformClick(); * return true; * } * return base.ProcessCmdKey(ref msg, keyData); * } */ } else if (((body.HandRightState == HandState.Open || body.HandRightState == HandState.Lasso) && wasRightGrip) && ((body.HandLeftState == HandState.Open || body.HandLeftState == HandState.Lasso) && wasLeftGrip)) { //this is for release and navigate windows in magnified state //release grips and keyboard commands wasRightGrip = false; wasLeftGrip = false; } } } else if (handRight.Z - spineBase.Z < -0.15f) // if right hand lift forward { /* * hand x calculated by this. we don't use shoulder right as a reference cause the shoulder right * is usually behind the lift right hand, and the position would be inferred and unstable. * because the spine base is on the left of right hand, we plus 0.05f to make it closer to the right. */ float x; this.right_x = x = handRight.X - spineBase.X + 0.05f; /* * hand y calculated by this. ss spine base is way lower than right hand, we plus 0.51f to make it * higher, the value 0.51f is worked out by testing for a several times, you can set it as another one you like. */ float y; this.right_y = y = spineBase.Y - handRight.Y + 0.51f; this.right_z = spineBase.Z - handRight.Z; // get current cursor position Point curPos = MouseControl.GetCursorPosition(); // smoothing for using should be 0 - 0.95f. The way we smooth the cusor is: oldPos + (newPos - oldPos) * smoothValue float smoothing = 1 - cursorSmoothing; // set cursor position MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); alreadyTrackedPos = true; // Grip gesture if (doClick && useGripGesture) { if ((body.HandRightState == HandState.Closed) && !wasRightGrip) { MouseControl.MouseLeftDown(); wasRightGrip = true; } else if ((body.HandRightState == HandState.Open || body.HandRightState == HandState.Lasso) && wasRightGrip) { MouseControl.MouseLeftUp(); wasRightGrip = false; } } } else if (handLeft.Z - spineBase.Z < -0.15f) // if left hand lift forward { float x; this.left_x = x = handLeft.X - spineBase.X + 0.3f; float y; this.left_y = y = spineBase.Y - handLeft.Y + 0.51f; this.left_z = spineBase.Z - handLeft.Z; Point curPos = MouseControl.GetCursorPosition(); float smoothing = 1 - cursorSmoothing; MouseControl.SetCursorPos((int)(curPos.X + (x * mouseSensitivity * screenWidth - curPos.X) * smoothing), (int)(curPos.Y + ((y + 0.25f) * mouseSensitivity * screenHeight - curPos.Y) * smoothing)); alreadyTrackedPos = true; if (doClick && useGripGesture) { if ((body.HandLeftState == HandState.Closed) && !wasLeftGrip) { MouseControl.MouseLeftDown(); wasLeftGrip = true; } else if ((body.HandLeftState == HandState.Open || body.HandLeftState == HandState.Lasso) && wasLeftGrip) { MouseControl.MouseLeftUp(); wasLeftGrip = false; } } } else { wasLeftGrip = true; wasRightGrip = true; alreadyTrackedPos = false; } // get first tracked body only break; } } }