/// <summary> /// Constructor. /// </summary> /// <param name="gesture">The Gesture to recognize.</param> /// <param name="skeleton">The skeleton that had the gesture in it</param> public GestureRecognizer(Gesture gesture, Skeleton skeleton) { Gesture = gesture; CurrentPoseIndex = -1; InvalidFrameCount = 0; InitialAnchorPosition = skeleton.Joints[gesture.AnchorJoint].Position; UpdateArmLength(skeleton); }
void recognizer_Recognized(object sender, PoseEventArgs e) { string[] poses = e.Poses; HashSet<GestureRecognizer> toAdd = new HashSet<GestureRecognizer>(); // Find gestures that start with this pose foreach (Gesture g in Gestures) { if (poses.Contains(g.PoseList[0])) { GestureRecognizer existing = ActiveGestures.Find((GestureRecognizer gr) => { return gr.Gesture == g && gr.CurrentPoseIndex <= 0; }); if (existing != null) { existing.UpdatedTime = DateTime.Now.Ticks; } else { GestureRecognizer gr = new GestureRecognizer(g, e.Skeleton); toAdd.Add(gr); } } } HashSet<GestureRecognizer> toRemove = new HashSet<GestureRecognizer>(); // Evaluate Active Gestures foreach (GestureRecognizer gr in ActiveGestures) { // If a gesture was recognized if (gr.EvaluatePose(poses, e.Skeleton)) { if (gr.Gesture.IsMirror(LastGesture)) { toRemove.Add(gr); long now = DateTime.Now.Ticks; if (gr.UpdatedTime - LastGestureTime <= MIRROR_DETECT_DELAY) { continue; } } // Clear all active gestures ActiveGestures.Clear(); // Calculate gesture speed double distance = CalculateDistance(gr.FinalAnchorPosition, gr.InitialAnchorPosition); long age = DateTime.Now.Ticks - gr.CreatedTime; //double speed = Math.Sqrt(distance / (age/15000000.0))*2.0; //Console.WriteLine("Age:\t{0}\nSpeed:\t{1}\nRatio:\t{2}\n\n", age, speed, distance/gr.SkeletonHeight); double speed = 3.0 * (distance / gr.SkeletonHeight); // Trigger event LastGesture = gr.Gesture; LastGestureTime = DateTime.Now.Ticks; OnGestureDetected(gr.Gesture, speed); break; } else if (gr.Expired) { toRemove.Add(gr); } else if (gr.InvalidFrameCount >= MAX_INVALID_FRAMES) { toRemove.Add(gr); if (gr.Gesture == LastGesture || gr.Gesture.IsMirror(LastGesture)) { LastGesture = null; } } } ActiveGestures.RemoveAll((GestureRecognizer gr) => { return toRemove.Contains(gr); }); ActiveGestures.AddRange(toAdd); }
/// <summary> /// Detects if a gesture has the exact opposite pose list as this one /// </summary> /// <param name="g">Gesture to check</param> /// <returns>True if the gesture is an exact mirror of this one</returns> public bool IsMirror(Gesture g) { if (g == null || g.PoseList.Length != this.PoseList.Length) { return false; } int length = g.PoseList.Length; for (int ii = 0; ii < (length + 1) / 2; ++ii) { if (g.PoseList[ii] != this.PoseList[length - ii - 1]) { return false; } } return true; }
/// <summary> /// When a Gesture is recognized, fire the GestureDetected event. /// </summary> /// <param name="g">The recognized Gesture.</param> private void OnGestureDetected(Gesture g, double executionSpeedRatio) { if (GestureDetected != null) { GestureDetected(this, new GestureEventArgs(g.Name, executionSpeedRatio)); } }