/// <summary> /// Gets dynamic features from the entire buffer. /// </summary> /// <param name="hand">Hand</param> /// <returns>Dynamic features</returns> public DynamicFeatures GetDynamicFeatures(String hand) { if (hand != "Left" && hand != "Right") { throw new Exception("Hand should have one of the following values: Left, Right."); } if (_queue.Count < FRAME_BUFFER_SIZE / 2) { return(null); } DynamicFeatures features = new DynamicFeatures(); _mutex.WaitOne(); foreach (FrameData frame in _queue) { if (hand == "Left") { if (frame.LeftGesture != null) { features.RecognizedGestures.Add(frame.LeftGesture.Name); } else { features.RecognizedGestures.Add(""); } if (frame.LeftJoints["elbow"].TrackingState != TrackingState.NotTracked && frame.LeftJoints["hand"].TrackingState != TrackingState.NotTracked) { float dx = frame.LeftJoints["elbow"].Position.X - frame.LeftJoints["hand"].Position.X; float dy = frame.LeftJoints["elbow"].Position.Y - frame.LeftJoints["hand"].Position.Y; features.HandElbowOffsets.Add(new PointF(dx, dy)); } else { features.HandElbowOffsets.Add(new PointF(0, 0)); } } else // Right { if (frame.RightGesture != null) { features.RecognizedGestures.Add(frame.RightGesture.Name); } else { features.RecognizedGestures.Add(""); } if (frame.RightJoints["elbow"].TrackingState != TrackingState.NotTracked && frame.RightJoints["hand"].TrackingState != TrackingState.NotTracked) { float dx = frame.RightJoints["elbow"].Position.X - frame.RightJoints["hand"].Position.X; float dy = frame.RightJoints["elbow"].Position.Y - frame.RightJoints["hand"].Position.Y; features.HandElbowOffsets.Add(new PointF(dx, dy)); } else { features.HandElbowOffsets.Add(new PointF(0, 0)); } } } _mutex.ReleaseMutex(); return(features); }
/// <summary> /// Recognizes dynamic gesture across series of frames. /// </summary> /// <returns>Gesture, if any</returns> public DynamicGesture RecognizeDynamicGesture() { DynamicFeatures features = _frameBuffer.GetDynamicFeatures(Hand); if (features == null) { return(null); } foreach (DynamicGesture gesture in DynamicGestures) { // Wave gesture recognition if (gesture.Type == DynamicGestureType.DynamicGestureWave) { int gestureCount = features.RecognizedGestures.Count(s => s == gesture.Gestures[0].Name); int positiveYCount = features.HandElbowOffsets.Count(p => p.Y < 0); double maxX = -999; double minX = 999; foreach (PointF offset in features.HandElbowOffsets) { if (offset.X > maxX) { maxX = offset.X; } if (offset.X < minX) { minX = offset.X; } } double gestureCutoff = features.RecognizedGestures.Count * 0.4; double positiveYCutoff = features.HandElbowOffsets.Count * 0.9; double offsetCutoff = 0.12; if (gestureCount > gestureCutoff && positiveYCount > positiveYCutoff && maxX - minX > offsetCutoff) { gesture.RecognizedData.Hand = Hand; return(gesture); } } // Alternation gesture recognition else if (gesture.Type == DynamicGestureType.DynamicGestureAlternation) { int countA = 0; int countB = 0; foreach (String s in features.RecognizedGestures) { if (s == gesture.Gestures[0].Name) { countA++; } else if (s == gesture.Gestures[1].Name) { countB++; } } double cutoff = features.RecognizedGestures.Count * 0.3; if (countA > cutoff && countB > cutoff) { gesture.RecognizedData.Hand = Hand; return(gesture); } } } return(null); }