Browse Source

documented Recognition.TouchRecognition

Alexander Hendrich 10 years ago
parent
commit
feda2b693f

+ 1 - 1
bbiwarg/Recognition/PalmRecognition/PalmTracker.cs

@@ -64,7 +64,7 @@ namespace bbiwarg.Recognition.PalmRecognition
         /// <summary>
         /// Gets all optimized representations of all tracked palms.
         /// </summary>
-        /// <returns>all tracked palms</returns>
+        /// <returns>all optimized tracked palms</returns>
         private List<Palm> getOptimizedPalms()
         {
             List<Palm> optimizedPalms = new List<Palm>();

+ 24 - 0
bbiwarg/Recognition/TouchRecognition/Touch.cs

@@ -12,14 +12,38 @@ using Emgu.CV.Structure;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    /// <summary>
+    /// Represents a touch (Finger<->Palm)
+    /// </summary>
     public class Touch : TrackableObject
     {
+        /// <summary>
+        /// the absolute position of the touch
+        /// </summary>
         public Vector2D AbsolutePosition { get; private set; }
+
+        /// <summary>
+        /// the relative position of the touch within the palm quad
+        /// </summary>
         public Vector2D RelativePosition { get; private set; }
+
+        /// <summary>
+        /// the touching finger
+        /// </summary>
         public Finger Finger { get; private set; }
+
+        /// <summary>
+        /// the touched palm
+        /// </summary>
         public Palm Palm { get; private set; }
 
 
+        /// <summary>
+        /// Initializes a new instance of the Touch class.
+        /// </summary>
+        /// <param name="absolutePosition">The absolute position.</param>
+        /// <param name="finger">The touching finger.</param>
+        /// <param name="palm">The touched palm.</param>
         public Touch(Vector2D absolutePosition, Finger finger, Palm palm)
         {
             AbsolutePosition = absolutePosition;

+ 58 - 20
bbiwarg/Recognition/TouchRecognition/TouchDetector.cs

@@ -15,13 +15,35 @@ using bbiwarg.Input.InputHandling;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    /// <summary>
+    /// Detects touches by flood filling around a small area around each finger tip and counting the number of affected pixels. If the finger is touching or slightly hovering above something, the flood fill spreads into the touched object and the number of affected pixels is higher.
+    /// </summary>
     class TouchDetector
     {
+        /// <summary>
+        /// the depth image of the current frame
+        /// </summary>
         private DepthImage depthImage;
+
+        /// <summary>
+        /// the fingers of the current frame
+        /// </summary>
         private List<Finger> fingers;
+
+        /// <summary>
+        /// the palms of the current frame
+        /// </summary>
         private List<Palm> palms;
+
+        /// <summary>
+        /// the detected touches in the current frame
+        /// </summary>
         private List<Touch> touches;
 
+        /// <summary>
+        /// Detects touches in the current frame and stores them in frameData.detectedTouchEvents
+        /// </summary>
+        /// <param name="frameData">the current frame</param>
         public void detectTouches(FrameData frameData)
         {
             depthImage = frameData.DepthImage;
@@ -30,40 +52,56 @@ namespace bbiwarg.Recognition.TouchRecognition
             touches = new List<Touch>();
 
             if (palms.Count > 0)
-                detectTouch();
+            {
+                foreach (Finger finger in fingers)
+                {
+                    Touch touch = detectTouch(finger);
+                    if (touch != null)
+                        touches.Add(touch);
+                }
+            }
 
             frameData.DetectedTouches = touches;
         }
 
-        private void detectTouch()
+        /// <summary>
+        /// Detects if a finger is touching a palm and either returns a new Touch or null
+        /// </summary>
+        /// <param name="finger">the fingers</param>
+        /// <returns>a new Touch or null</returns>
+        private Touch detectTouch(Finger finger)
         {
-            foreach (Finger finger in fingers)
-            {
-                Vector2D tipPoint = finger.TipPoint;
-                Vector2D direction = finger.Direction;
-                Vector2D tipPointInside = tipPoint.moveWithinBound(depthImage.Size, direction.getInverse(), Parameters.TouchTipInsideFactor);
-                Vector2D tipPointOutside = tipPoint.moveWithinBound(depthImage.Size, direction, Parameters.TouchTipOutsideFactor);
+            Vector2D tipPoint = finger.TipPoint;
+            Vector2D direction = finger.Direction;
+            Vector2D tipPointInside = tipPoint.moveWithinBound(depthImage.Size, direction.getInverse(), Parameters.TouchTipInsideFactor);
+            Vector2D tipPointOutside = tipPoint.moveWithinBound(depthImage.Size, direction, Parameters.TouchTipOutsideFactor);
 
-                foreach (Palm palm in palms)
+            foreach (Palm palm in palms)
+            {
+                if (palm.isInside(tipPointOutside))
                 {
-                    if (palm.isInside(tipPointOutside))
-                    {
-                        Image<Gray, byte> touchMask = getTouchMask(tipPointInside);
+                    Image<Gray, byte> touchMask = getTouchMask(tipPointInside);
 
-                        int touchPixels = touchMask.CountNonzero()[0];
-                        int numPixels = touchMask.Width * touchMask.Height;
-                        float touchValue = touchPixels / (float)numPixels;
+                    int touchPixels = touchMask.CountNonzero()[0];
+                    int numPixels = touchMask.Width * touchMask.Height;
+                    float touchValue = touchPixels / (float)numPixels;
 
-                        if (touchValue > Parameters.TouchMinTouchValue)
-                        {
-                            Touch touchEvent = new Touch(tipPointOutside, finger, palm);
-                            touches.Add(touchEvent);
-                        }
+                    if (touchValue > Parameters.TouchMinTouchValue)
+                    {
+                        Touch touch = new Touch(tipPointOutside, finger, palm);
+                        return touch;
                     }
                 }
             }
+
+            return null;
         }
 
+        /// <summary>
+        /// Gets an image of a small area around the desired touch point (copied from the depth image)
+        /// </summary>
+        /// <param name="touchPoint">the touch position</param>
+        /// <returns>image of the touch area around the touch position</returns>
         private Image<Gray, byte> getTouchMask(Vector2D touchPoint)
         {
             int minX = Math.Max(touchPoint.IntX - 2 * Parameters.TouchAreaSize / 3, 0);

+ 18 - 0
bbiwarg/Recognition/TouchRecognition/TouchEvent.cs

@@ -6,6 +6,9 @@ using System.Threading.Tasks;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    /// <summary>
+    /// The type of the touch event.
+    /// </summary>
     public enum TouchEventType
     {
         Down,
@@ -13,11 +16,26 @@ namespace bbiwarg.Recognition.TouchRecognition
         Up
     }
 
+    /// <summary>
+    /// Represents a touch event (typ+touch)
+    /// </summary>
     public class TouchEvent
     {
+        /// <summary>
+        /// the type of the touch event
+        /// </summary>
         public TouchEventType Type { get; private set; }
+
+        /// <summary>
+        /// the touch of the touch event
+        /// </summary>
         public Touch Touch { get; private set; }
 
+        /// <summary>
+        /// Initializes a new instance of the TouchEvent class.
+        /// </summary>
+        /// <param name="type">The type.</param>
+        /// <param name="touch">The touch.</param>
         public TouchEvent(TouchEventType type, Touch touch)
         {
             Type = type;

+ 29 - 0
bbiwarg/Recognition/TouchRecognition/TouchTracker.cs

@@ -12,16 +12,30 @@ using bbiwarg.Input.InputHandling;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    /// <summary>
+    /// Keeps track of touches over a period of time and generates touch events
+    /// </summary>
     class TouchTracker : Tracker<Touch, TrackedTouch>
     {
+        /// <summary>
+        /// the touch events in the current frame
+        /// </summary>
         private List<TouchEvent> touchEvents;
 
+        /// <summary>
+        /// Initializes a new instance of the TouchTracker class.
+        /// </summary>
+        /// <param name="imageSize">Size of the input image.</param>
         public TouchTracker(ImageSize imageSize)
             : base(imageSize)
         {
             touchEvents = new List<TouchEvent>();
         }
 
+        /// <summary>
+        /// Updates the tracked touches, and stores the (optimized) touches in frameData.trackedTouches and the touch events in frameData.touchEvents.
+        /// </summary>
+        /// <param name="frameData"></param>
         public void trackTouches(FrameData frameData)
         {
             trackObjects(frameData.DetectedTouches);
@@ -29,11 +43,22 @@ namespace bbiwarg.Recognition.TouchRecognition
             frameData.TouchEvents = flushTouchEvents();
         }
 
+        /// <summary>
+        /// Calculates the similarity [0-1] of a tracked touch and a detected touch.
+        /// </summary>
+        /// <param name="trackedTouch">the tracked touch</param>
+        /// <param name="detectedTouch">the detected touch</param>
+        /// <returns>the similarity</returns>
         public override float calculateSimilarity(TrackedTouch trackedTouch, Touch detectedTouch)
         {
             return (trackedTouch.FingerID == detectedTouch.Finger.TrackID) ? 1 : 0;
         }
 
+        /// <summary>
+        /// Creates a new TrackedTouch
+        /// </summary>
+        /// <param name="detectedObject">the detected touch</param>
+        /// <returns>a new TrackedTouch</returns>
         protected override TrackedTouch createTrackedObject(Touch detectedObject)
         {
             TrackedTouch tt = new TrackedTouch(idPool.getNextUnusedID(), detectedObject, Parameters.TouchTrackerNumFramesDetectedUntilTracked, Parameters.TouchTrackerNumFramesLostUntilDeleted);
@@ -41,6 +66,10 @@ namespace bbiwarg.Recognition.TouchRecognition
             return tt;
         }
 
+        /// <summary>
+        /// Get all optimized representations of all tracked touches
+        /// </summary>
+        /// <returns>all optimized tracked touches</returns>
         private List<Touch> getOptimizedTouches()
         {
             List<Touch> optimizedTouchs = new List<Touch>();

+ 56 - 0
bbiwarg/Recognition/TouchRecognition/TrackedTouch.cs

@@ -8,19 +8,55 @@ using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.TouchRecognition
 {
+    /// <summary>
+    /// signature of the touchEvent event
+    /// </summary>
+    /// <param name="sender">the event sender</param>
+    /// <param name="e">the touch event</param>
     public delegate void TouchEventHandler(object sender, TouchEvent e);
     
+    /// <summary>
+    /// Represents a touch that is tracked for several frames
+    /// </summary>
     public class TrackedTouch : TrackedObject<Touch>
     {
+        /// <summary>
+        /// the kalman filter for the absolute position prediction
+        /// </summary>
         private Kalman2DPositionFilter absolutePositionKalman;
 
+        /// <summary>
+        /// the prediction of the absolute position
+        /// </summary>
         public Vector2D AbsolutePositionPrediction { get { return absolutePositionKalman.getPrediction(); } }
+
+        /// <summary>
+        /// the optimized touch (using the predicted absolute position)
+        /// </summary>
         public Touch OptimizedTouch { get; private set; }
+
+        /// <summary>
+        /// indicates if the touch is currently active
+        /// </summary>
         public bool IsTouchActive { get; private set; }
+
+        /// <summary>
+        /// the track ID of the touching finger
+        /// </summary>
         public int FingerID { get; private set; }
 
+        /// <summary>
+        /// the event which is fired, if a touchEvent occurs
+        /// </summary>
         public event TouchEventHandler TouchEvent;
 
+        /// <summary>
+        /// Initializes a new instance of the TrackedTouch class.
+        /// </summary>
+        /// <param name="id">The track ID.</param>
+        /// <param name="detectedTouch">The detected touch.</param>
+        /// <param name="numFramesDetectedUntilTracked">The number of consecutive frames detected until the touch is considered to be tracked (touchDown).</param>
+        /// <param name="numFramesLostUntilDeleted">The number of consecutive frames lost until the touch is deleted (touchUp).</param>
         public TrackedTouch(int id, Touch detectedTouch, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
             : base(id, detectedTouch, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
         {
@@ -33,6 +69,10 @@ namespace bbiwarg.Recognition.TouchRecognition
             logStateChange();
         }
 
+        /// <summary>
+        /// Updates the tracked touch, logs the state change, updates the optimized touch and the absolute position predicton and triggers touch events.
+        /// </summary>
+        /// <param name="detectedTouch">the detected touch</param>
         public override void updateFrame(Touch detectedTouch)
         {
             base.updateFrame(detectedTouch);
@@ -59,17 +99,27 @@ namespace bbiwarg.Recognition.TouchRecognition
 
         }
 
+        /// <summary>
+        /// Updates the optimized touch using the absolute position prediction
+        /// </summary>
+        /// <param name="detectedTouch">the detected touch</param>
         private void updateOptimizedTouch(Touch detectedTouch)
         {
             OptimizedTouch = new Touch(AbsolutePositionPrediction, detectedTouch.Finger, detectedTouch.Palm);
         }
 
+        /// <summary>
+        /// logs the state change
+        /// </summary>
         private void logStateChange()
         {
             String stateAsString = CurrentState.ToString().ToLower();
             Logger.log(String.Format("Touch #{0} {1}", this.ID, stateAsString), LogSubject.TouchTracker);
         }
 
+        /// <summary>
+        /// Fires a touch event with type = down
+        /// </summary>
         private void TriggerTouchDown()
         {
             if (TouchEvent != null)
@@ -79,6 +129,9 @@ namespace bbiwarg.Recognition.TouchRecognition
             }
         }
 
+        /// <summary>
+        /// Fires a touch event with type = move
+        /// </summary>
         private void TriggerTouchMove()
         {
             if (TouchEvent != null)
@@ -87,6 +140,9 @@ namespace bbiwarg.Recognition.TouchRecognition
             }
         }
 
+        /// <summary>
+        /// Fires a touch event with type = up
+        /// </summary>
         private void TriggerTouchUp()
         {
             if (TouchEvent != null)