Browse Source

Merge branch 'master' of https://git.tk.informatik.tu-darmstadt.de/etri-smartspaces

Anton Rohr 10 years ago
parent
commit
0a439304f6

+ 4 - 4
bbiwarg/Input/InputProviding/InputProvider.cs

@@ -102,12 +102,12 @@ namespace bbiwarg.Input.InputProviding
         protected IParameterHandle<int> height;
 
         /// <summary>
-        /// parameter handle for the horizontal field of view
+        /// parameter handle for the horizontal field of view angle
         /// </summary>
         protected IParameterHandle<float> hfov;
 
         /// <summary>
-        /// parameter handle for the vertical field of view
+        /// parameter handle for the vertical field of view angle
         /// </summary>
         protected IParameterHandle<float> vfov;
 
@@ -132,12 +132,12 @@ namespace bbiwarg.Input.InputProviding
         public int ImageHeight { get { return height.Value; } }
 
         /// <summary>
-        /// the horizontal field of view
+        /// the horizontal field of view angle
         /// </summary>
         public float HFOV { get { return hfov.Value; } }
 
         /// <summary>
-        /// the vertical field of view
+        /// the vertical field of view angle
         /// </summary>
         public float VFOV { get { return vfov.Value; } }
 

+ 47 - 0
bbiwarg/Recognition/FingerRecognition/Finger.cs

@@ -14,27 +14,74 @@ using Emgu.CV;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// The Finger class represents a Finger.
+    /// </summary>
     public class Finger : TrackableObject
     {
+        /// <summary>
+        /// the position of the finger tip
+        /// </summary>
         public Vector2D TipPoint { get { return SliceTrail.StartSlice.Mid; } }
+
+        /// <summary>
+        /// the position of the finger end (hand)
+        /// </summary>
         public Vector2D HandPoint { get { return SliceTrail.EndSlice.Mid; } }
+
+        /// <summary>
+        /// a position in the middle of the finger
+        /// </summary>
         public Vector2D MidPoint { get { return SliceTrail.MidSlice.Mid; } }
+
+        /// <summary>
+        /// the direction of the finger (end to start)
+        /// </summary>
         public Vector2D Direction { get { return SliceTrail.FittedDirection; } }
+
+        /// <summary>
+        /// the line segment from start to end
+        /// </summary>
         public LineSegment2D LineSegment { get { return SliceTrail.LineSegment; } }
+
+        /// <summary>
+        /// the finger slices
+        /// </summary>
         public FingerSliceTrail SliceTrail { get; private set; }
+
+        /// <summary>
+        /// the hand the finger belongs to
+        /// </summary>
         public Hand Hand { get; set; }
+
+        /// <summary>
+        /// the touch of the current finger
+        /// </summary>
         public Touch Touch { get; set; }
 
+
+        /// <summary>
+        /// Initializes a new instance of the Finger class.
+        /// </summary>
+        /// <param name="sliceTrail">The finger slice trail.</param>
         public Finger(FingerSliceTrail sliceTrail)
             : base()
         {
             SliceTrail = sliceTrail;
         }
 
+        /// <summary>
+        /// Reverses the finger (start<->end)
+        /// </summary>
         public void reverse() {
             SliceTrail.reverse();
         }
 
+        /// <summary>
+        /// Gets a contour of the finger
+        /// </summary>
+        /// <param name="margin">the margin around the finger (distance in pixels)</param>
+        /// <returns>the contour of the finger</returns>
         public Contour<Point> getContour(float margin) {
             return SliceTrail.getContour(margin);
         }

+ 80 - 2
bbiwarg/Recognition/FingerRecognition/FingerDetector.cs

@@ -13,18 +13,48 @@ using Emgu.CV;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// Detects fingers in the given depth and edge images. The finger detection searches for edges in the edge image and tries to find an initial finger slice. For each found finger slice, the finger detector tries to move along the finger direction to extend the finger slice trail. If the trail reaches its end, the finger detector removes the first few slices and starts the trail expansion in opposite direction. If the complete slice trail is long enough, the finger slices are sorted into correct order and the edges around the finger are removed to increase performance for the next finger detection.
+    /// </summary>
     class FingerDetector
     {
+        /// <summary>
+        /// the coordinateConverter (used to calculate finger width (in milimeters))
+        /// </summary>
         private CoordinateConverter coordinateConverter;
+
+        /// <summary>
+        /// the current depthImage
+        /// </summary>
         private DepthImage depthImage;
+
+        /// <summary>
+        /// the current edge image in its original form
+        /// </summary>
         private EdgeImage edgeImageOriginal;
+
+        /// <summary>
+        /// the current edge image in its adapted form (edges around detected fingers will be removed)
+        /// </summary>
         private EdgeImage edgeImageAdapted;
+
+        /// <summary>
+        /// the detected fingers
+        /// </summary>
         private List<Finger> fingers;
 
+        /// <summary>
+        /// Initializes a new instance of the FingerDetector class.
+        /// </summary>
+        /// <param name="coordinateConverter">The coordinate converter.</param>
         public FingerDetector(CoordinateConverter coordinateConverter) {
             this.coordinateConverter = coordinateConverter;
         }
-
+        
+        /// <summary>
+        /// Detects fingers in the current frame using the depth and edge image. Afterwards the detected fingers are stored in the given frame data (detectedFingers).
+        /// </summary>
+        /// <param name="frameData">the current frame</param>
         public void detectFingers(FrameData frameData)
         {
             depthImage = frameData.DepthImage;
@@ -67,6 +97,11 @@ namespace bbiwarg.Recognition.FingerRecognition
             frameData.DetectedFingers = fingers;
         }
 
+        /// <summary>
+        /// Gets the edge direction of the given edge point. The edge direction is either horizontal, vertical, diagonal (both) or null.
+        /// </summary>
+        /// <param name="edgePoint">the edge point</param>
+        /// <returns>the edge directon at the given point</returns>
         private Vector2D getEdgeDirection(Vector2D edgePoint)
         {
             int x = edgePoint.IntX;
@@ -79,6 +114,12 @@ namespace bbiwarg.Recognition.FingerRecognition
             else return null;
         }
 
+        /// <summary>
+        /// Creates a new FingerSliceTrail and expands it along its direction.
+        /// </summary>
+        /// <param name="startSlice">the initial finger slice</param>
+        /// <param name="startDirection">the initial finger direction</param>
+        /// <returns>the found FingerSliceTrail or null</returns>
         private FingerSliceTrail findFingerSliceTrail(FingerSlice startSlice, Vector2D startDirection)
         {
             FingerSliceTrail trail = new FingerSliceTrail(startSlice);
@@ -105,6 +146,12 @@ namespace bbiwarg.Recognition.FingerRecognition
             return null;
         }
 
+        /// <summary>
+        ///  Tries to expand a trail along its direction.
+        /// </summary>
+        /// <param name="trail">the given finger slice trail</param>
+        /// <param name="reversed">indicates in which direction the trail should be expanded</param>
+        /// <returns>the expanded finger slice trail</returns>
         private FingerSliceTrail expandTrail(FingerSliceTrail trail, bool reversed = false)
         {
             if (reversed)
@@ -146,6 +193,13 @@ namespace bbiwarg.Recognition.FingerRecognition
             return trail;
         }
 
+        /// <summary>
+        /// Tries to find a finger slice from a given position by searching in both orthogonal directions for an edge.
+        /// </summary>
+        /// <param name="position">the position somewhere in the middle of the possible finger</param>
+        /// <param name="direction">the finger direction</param>
+        /// <param name="reversed">indicates wether start and end should be swapped</param>
+        /// <returns>the found finger slice or null</returns>
         private FingerSlice findFingerSliceFromMid(Vector2D position, Vector2D direction, bool reversed = false)
         {
             if (edgeImageAdapted.isRoughEdgeAt(position)) return null;
@@ -171,6 +225,12 @@ namespace bbiwarg.Recognition.FingerRecognition
             return slice;
         }
 
+        /// <summary>
+        /// Tries to find a finger slice from one point towards the given direction (searches for an edge).
+        /// </summary>
+        /// <param name="start">the start position</param>
+        /// <param name="direction">the slice direction</param>
+        /// <returns>the found finger slice or null</returns>
         private FingerSlice findFingerSliceFromStartEdge(Vector2D start, Vector2D direction)
         {
             Vector2D searchStart = start + Parameters.FingerMinWidth2D * direction;
@@ -189,6 +249,11 @@ namespace bbiwarg.Recognition.FingerRecognition
             return slice;
         }
 
+        /// <summary>
+        /// Checks if a possible finger slice is located on a finger. To pass this test, the depth value at the mid has to be lower than on the outside (start and end).
+        /// </summary>
+        /// <param name="slice">the possible finger slcie</param>
+        /// <returns>wether the slice is located on a finger</returns>
         private bool fingerSliceDepthTest(FingerSlice slice)
         {
             Int16 depthStart = depthImage.getDepthAt(slice.Start.moveWithinBound(depthImage.Size, slice.Direction.getInverse(), Parameters.FingerContourMargin));
@@ -197,6 +262,10 @@ namespace bbiwarg.Recognition.FingerRecognition
             return (depthStart > depthMid && depthMid < depthEnd);
         }
 
+        /// <summary>
+        /// Sorts the finger slices in correct order an checks if the finger is a valid finger (<see cref="isCrippleFinger(Finger)"/>). If it is valid the finger is added to the list of detected fingers. Afterwards the edges around the finger are removed to surpress a new finger search for the same finger.
+        /// </summary>
+        /// <param name="trail">the slice trail of the possible finger</param>
         private void createFingerFromTrail(FingerSliceTrail trail)
         {
             //bring finger in correct direction Tip->Hand
@@ -213,6 +282,11 @@ namespace bbiwarg.Recognition.FingerRecognition
             edgeImageAdapted.removeEdgesInsidePolygon(finger.getContour(Parameters.FingerContourMargin).ToArray());
         }
 
+        /// <summary>
+        /// Checks wether the finger has enough space around itself (fingers from a closed hand shouldn't bee detected).
+        /// </summary>
+        /// <param name="finger">the finger</param>
+        /// <returns>wether the finger has enough space around itself</returns>
         private bool isCrippleFinger(Finger finger)
         {
             FingerSlice midSlice = finger.SliceTrail.MidSlice;
@@ -227,7 +301,11 @@ namespace bbiwarg.Recognition.FingerRecognition
             return (minDepthDifference < Parameters.FingerMaxCrippleDifference);
         }
 
-
+        /// <summary>
+        /// Sorts a slice trail in the corrent order, so that the start is at the finger tip and the end is at the hand. To guess the correct order the width of the first and last slice are compared.
+        /// </summary>
+        /// <param name="trail">the slice trail of the finger</param>
+        /// <returns>the slice trail of the finger in correct order</returns>
         private FingerSliceTrail orderTrailTipToHand(FingerSliceTrail trail)
         {
             float startLength = trail.StartSlice.Length;

+ 32 - 0
bbiwarg/Recognition/FingerRecognition/FingerSlice.cs

@@ -7,15 +7,47 @@ using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// A Finger consists of multiple FingerSlices, each one represented by a line preferrably orthogonal to the fingers direction.
+    /// </summary>
     public class FingerSlice
     {
+        /// <summary>
+        /// the point in the middle of the slice
+        /// </summary>
         public Vector2D Mid { get; private set; }
+
+        /// <summary>
+        /// the start point of the slice
+        /// </summary>
         public Vector2D Start { get; private set; }
+
+        /// <summary>
+        /// the end point of the slice
+        /// </summary>
         public Vector2D End { get; private set; }
+
+        /// <summary>
+        /// the line segment connecting start and end
+        /// </summary>
         public LineSegment2D LineSegment { get; private set; }
+
+        /// <summary>
+        /// the direction of the slice
+        /// </summary>
         public Vector2D Direction { get { return LineSegment.Direction; } }
+
+        /// <summary>
+        /// the length of the slice (in pixels)
+        /// </summary>
         public float Length { get { return LineSegment.Length; } }
 
+
+        /// <summary>
+        /// Initializes a new instance of the FingerSlice class.
+        /// </summary>
+        /// <param name="start">The start point</param>
+        /// <param name="end">The end point</param>
         public FingerSlice(Vector2D start, Vector2D end)
         {
             Start = start;

+ 92 - 2
bbiwarg/Recognition/FingerRecognition/FingerSliceTrail.cs

@@ -9,22 +9,78 @@ using Emgu.CV;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// Each Finger consists of multiple FingerSlices, a FingerSliceTrail is a collection of these slices.
+    /// </summary>
     public class FingerSliceTrail
     {
+        /// <summary>
+        /// the line segment connection the first slice's mid to the last slice's mid
+        /// </summary>
         private LineSegment2D lineSegment;
+
+        /// <summary>
+        /// the fitted direction through all slice's mid points [end to start]
+        /// </summary>
         private Vector2D fittedDirection;
+
+        /// <summary>
+        /// indicates wether the variable lineSegment is up to date (outdates if new start or end slices are added)
+        /// </summary>
         private bool lineSegmentUpToDate;
+
+        /// <summary>
+        /// indicates weter the variable fittedDirection is up to date (outdates if new slices are added)
+        /// </summary>
         private bool fittedDirectionUpToDate;
 
+        /// <summary>
+        /// the finger slices
+        /// </summary>
         public List<FingerSlice> Slices { get; private set; }
+
+        /// <summary>
+        /// the first slice
+        /// </summary>
         public FingerSlice StartSlice { get { return Slices[0]; } }
+
+        /// <summary>
+        /// the middle slice
+        /// </summary>
         public FingerSlice MidSlice { get { return Slices[NumSlices / 2]; } }
+
+        /// <summary>
+        /// the last slice
+        /// </summary>
         public FingerSlice EndSlice { get { return Slices[Slices.Count - 1]; } }
+
+        /// <summary>
+        /// The slice at the given index.
+        /// </summary>
+        /// <param name="index">the index</param>
+        /// <returns>the slice at the given index</returns>
         public FingerSlice this[int index] { get { return Slices[index]; } }
+
+        /// <summary>
+        /// the number of slices
+        /// </summary>
         public int NumSlices { get { return Slices.Count; } }
+
+        /// <summary>
+        /// the line segment connecting the start slice's mid to the end slice's mid
+        /// </summary>
         public LineSegment2D LineSegment { get { if (!lineSegmentUpToDate) updateLineSegment(); return lineSegment; } }
+
+        /// <summary>
+        /// the fitted direction through all slice's mid points [end to start]
+        /// </summary>
         public Vector2D FittedDirection { get { if (!fittedDirectionUpToDate) updateFittedDirection(); return fittedDirection; } }
 
+
+        /// <summary>
+        /// Initializes a new instance of the FingerSliceTrail class.
+        /// </summary>
+        /// <param name="slice">The initial slice.</param>
         public FingerSliceTrail(FingerSlice slice)
         {
             Slices = new List<FingerSlice>();
@@ -33,6 +89,10 @@ namespace bbiwarg.Recognition.FingerRecognition
             fittedDirectionUpToDate = false;
         }
 
+        /// <summary>
+        /// Adds a slice to the end of the slice trail and outdates the lineSegment and fittedDirection.
+        /// </summary>
+        /// <param name="slice">the slice that should be added</param>
         public void addSlice(FingerSlice slice)
         {
             Slices.Add(slice);
@@ -40,18 +100,30 @@ namespace bbiwarg.Recognition.FingerRecognition
             fittedDirectionUpToDate = false;
         }
 
+        /// <summary>
+        /// Calculates the direction of the first few slices
+        /// </summary>
+        /// <returns>the start direction (pointing direction)</returns>
         public Vector2D getStartDirection()
         {
             int innerStartIndex = Math.Min(NumSlices - 1, Parameters.FingerNumSlicesForRelativeDirection);
             return (StartSlice.Mid - Slices[innerStartIndex].Mid).normalize();
         }
 
+        /// <summary>
+        /// Calculates the direction of the last few slices.
+        /// </summary>
+        /// <returns>the end direction (direction towards hand)</returns>
         public Vector2D getEndDirection()
         {
             int innerEndIndex = Math.Max(0, NumSlices - Parameters.FingerNumSlicesForRelativeDirection);
             return (EndSlice.Mid - Slices[innerEndIndex].Mid).normalize();
         }
 
+        /// <summary>
+        /// Removes the first few slices.
+        /// </summary>
+        /// <param name="numSlices">the number of slices that should be removed</param>
         public void removeFirstSlices(int numSlices)
         {
             Slices.RemoveRange(0, numSlices);
@@ -59,13 +131,25 @@ namespace bbiwarg.Recognition.FingerRecognition
             fittedDirectionUpToDate = false;
         }
 
+        /// <summary>
+        /// Reverses the trail and updates the line segment and the fitted direction
+        /// </summary>
         public void reverse()
         {
             Slices.Reverse();
-            lineSegmentUpToDate = false;
-            fittedDirectionUpToDate = false;
+
+            if(lineSegmentUpToDate)
+                lineSegment = new LineSegment2D(lineSegment.P2, lineSegment.P1);
+
+            if (fittedDirectionUpToDate)
+                fittedDirection = fittedDirection.getInverse();
         }
 
+        /// <summary>
+        /// Gets the contour of the finger with a given margin
+        /// </summary>
+        /// <param name="margin">the margin around the finger (in pixels)</param>
+        /// <returns>the contour of the finger</returns>
         public Contour<Point> getContour(float margin)
         {
             List<Point> pointsA = new List<Point>();
@@ -86,12 +170,18 @@ namespace bbiwarg.Recognition.FingerRecognition
             return contour;
         }
 
+        /// <summary>
+        /// updtes the line segment (new line segment from end to start)
+        /// </summary>
         private void updateLineSegment()
         {
             lineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid);
             lineSegmentUpToDate = true;
         }
 
+        /// <summary>
+        /// updates the fitted direction (line fitting through all slices mid points)
+        /// </summary>
         private void updateFittedDirection()
         {
             List<PointF> midPoints = new List<PointF>();

+ 22 - 0
bbiwarg/Recognition/FingerRecognition/FingerTracker.cs

@@ -9,18 +9,35 @@ using bbiwarg.Input.InputHandling;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// Tracks fingers over  multiple frames.
+    /// </summary>
     class FingerTracker : Tracker<Finger, TrackedFinger>
     {
+        /// <summary>
+        /// Initializes a new instance of the FingerTracker class.
+        /// </summary>
+        /// <param name="imageSize">Size of the input image.</param>
         public FingerTracker(ImageSize imageSize)
             : base(imageSize)
         {
         }
 
+        /// <summary>
+        /// Updates the TrackedFingers with the detected fingers in the current frame and stores the tracked fingers.
+        /// </summary>
+        /// <param name="frameData">the current frame</param>
         public void trackFingers(FrameData frameData) {
             trackObjects(frameData.DetectedFingers);
             frameData.TrackedFingers = getCurrentObjectsWithState(TrackingState.Tracked);
         }
 
+        /// <summary>
+        /// Calculates the similarity [0-1] of a tracked Finger and a detected finger 
+        /// </summary>
+        /// <param name="trackedFinger">the tracked finger</param>
+        /// <param name="detectedFinger">the detected finger</param>
+        /// <returns>the similarity between both fingers</returns>
         public override float calculateSimilarity(TrackedFinger trackedFinger, Finger detectedFinger)
         {
             Vector2D tip, hand;
@@ -41,6 +58,11 @@ namespace bbiwarg.Recognition.FingerRecognition
             return tipPointSimilarity * handPointSimilarity;
         }
 
+        /// <summary>
+        /// Creates a TrackedFinger.
+        /// </summary>
+        /// <param name="detectedObject">The detected finger.</param>
+        /// <returns>a TrackedFinger</returns>
         protected override TrackedFinger createTrackedObject(Finger detectedObject)
         {
             return new TrackedFinger(idPool.getNextUnusedID(), detectedObject, Parameters.FingerTrackerNumFramesDetectedUntilTracked, Parameters.FingerTrackerNumFramesLostUntilDeleted);

+ 45 - 0
bbiwarg/Recognition/FingerRecognition/TrackedFinger.cs

@@ -8,16 +8,49 @@ using bbiwarg.Utility;
 
 namespace bbiwarg.Recognition.FingerRecognition
 {
+    /// <summary>
+    /// Represents a finger that is tracked for several frames.
+    /// </summary>
     class TrackedFinger : TrackedObject<Finger>
     {
+        /// <summary>
+        /// the kalman filter for the tip point
+        /// </summary>
         private Kalman2DPositionFilter tipPointKalman;
+
+        /// <summary>
+        /// the kalman filter for the hand point
+        /// </summary>
         private Kalman2DPositionFilter handPointKalman;
+
+        /// <summary>
+        /// list of last directions (used to correct finger directions if they differ from average)
+        /// </summary>
         private List<Vector2D> lastRawDirections;
 
+        /// <summary>
+        /// predicted position of the tip point
+        /// </summary>
         public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
+
+        /// <summary>
+        /// predicted position of the hand point
+        /// </summary>
         public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
+
+        /// <summary>
+        /// the average direction of the last fingers
+        /// </summary>
         public Vector2D MeanDirection { get { return Vector2D.mean(lastRawDirections); } }
 
+
+        /// <summary>
+        /// Initializes a new instance of the TrackedFinger class.
+        /// </summary>
+        /// <param name="id">The track ID.</param>
+        /// <param name="detectedFinger">The initial detected finger.</param>
+        /// <param name="numFramesDetectedUntilTracked">The number of consecutive frames detected until the finger is considered to be tracked.</param>
+        /// <param name="numFramesLostUntilDeleted">The number of consecutive frames lost until the finger is considered to be deleted.</param>
         public TrackedFinger(int id, Finger detectedFinger, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
             : base(id, detectedFinger, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
         {
@@ -30,6 +63,10 @@ namespace bbiwarg.Recognition.FingerRecognition
             logStateChange();
         }
 
+        /// <summary>
+        /// Updates the tracked finger with its best match in the current frame, logs the state change, corrects the finger's direction if needed and updates the position predictions (kalman filters).
+        /// </summary>
+        /// <param name="detectedFinger">The detected finger.</param>
         public override void updateFrame(Finger detectedFinger)
         {
             base.updateFrame(detectedFinger);
@@ -51,12 +88,20 @@ namespace bbiwarg.Recognition.FingerRecognition
             }
         }
 
+        /// <summary>
+        /// Indicates wether a newly detected finger should be reverse (direction differs from average direction of previous fingers).
+        /// </summary>
+        /// <param name="detectedFinger">the detected finger</param>
+        /// <returns>wether the fingers direction matches to the direction of the previous fingers</returns>
         public bool shouldFingerBeReversed(Finger detectedFinger)
         {
             Vector2D meanDirection = Vector2D.mean(lastRawDirections);
             return meanDirection.isInOppositeDirection(detectedFinger.Direction);
         }
 
+        /// <summary>
+        /// logs the state change
+        /// </summary>
         private void logStateChange()
         {
             String stateAsString = CurrentState.ToString().ToLower();

+ 1 - 1
bbiwarg/Recognition/Tracking/Tracker.cs

@@ -138,7 +138,7 @@ namespace bbiwarg.Recognition.Tracking
         /// </summary>
         /// <param name="trackedObject">the tracked object</param>
         /// <param name="detectedObject">the detected trackable object</param>
-        /// <returns></returns>
+        /// <returns>the smiliarity [0-1]</returns>
         public abstract float calculateSimilarity(TrackedT trackedObject, T detectedObject);
 
         /// <summary>

+ 49 - 4
bbiwarg/Utility/ConvexityDefect.cs

@@ -8,20 +8,55 @@ using Emgu.CV.Structure;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// Stores data about and provides functions to work with convexity defects.
+    /// </summary>
     public class ConvexityDefect
     {
+        /// <summary>
+        /// the point of start and end point which is nearer to the depth point
+        /// </summary>
         public Vector2D OuterShort { get; private set; }
+        
+        /// <summary>
+        /// the point of start and end point which is farther away from the depth point
+        /// </summary>
         public Vector2D OuterLong { get; private set; }
+        
+        /// <summary>
+        /// the depth point
+        /// </summary>
         public Vector2D Inner { get; private set; }
+
+        /// <summary>
+        /// vector from Inner to OuterShort
+        /// </summary>
         public Vector2D VectorShort { get; private set; }
+
+        /// <summary>
+        /// vector from Inner to OuterLong
+        /// </summary>
         public Vector2D VectorLong { get; private set; }
+
+        /// <summary>
+        /// line segment from start to end point
+        /// </summary>
         public LineSegment2D OuterLineSegment { get; private set; }
+
+        /// <summary>
+        /// distance from OuterLineSegment to Inner
+        /// </summary>
         public float Depth { get; private set; }
 
-        public ConvexityDefect(MCvConvexityDefect mcvCOnvexityDefect) {
-            Inner = new Vector2D(mcvCOnvexityDefect.DepthPoint);
-            Vector2D p1 = new Vector2D(mcvCOnvexityDefect.StartPoint);
-            Vector2D p2 = new Vector2D(mcvCOnvexityDefect.EndPoint);
+
+        /// <summary>
+        /// Constructs a ConvexityDefect.
+        /// </summary>
+        /// <param name="mcvConvexityDefect">the emgu convexity defect which has start, end and depth point</param>
+        public ConvexityDefect(MCvConvexityDefect mcvConvexityDefect) {
+            Inner = new Vector2D(mcvConvexityDefect.DepthPoint);
+            Vector2D p1 = new Vector2D(mcvConvexityDefect.StartPoint);
+            Vector2D p2 = new Vector2D(mcvConvexityDefect.EndPoint);
 
             if ((p1 - Inner).Length > (p2 - Inner).Length)
             {
@@ -39,6 +74,11 @@ namespace bbiwarg.Utility
             Depth = OuterLineSegment.getDistanceTo(Inner);
         }
 
+        /// <summary>
+        /// Tests if this defect could be the defect near the thumb.
+        /// </summary>
+        /// <param name="thumb">finger representing the thumb</param>
+        /// <returns>true iff this defect is a possible thumb defect</returns>
         public bool isPossibleThumbDefect(Finger thumb) {
             float tipDistance = thumb.TipPoint.getDistanceTo(OuterShort);
             float handDistance = thumb.HandPoint.getDistanceTo(Inner);
@@ -51,6 +91,11 @@ namespace bbiwarg.Utility
                     shortLongLengthRatio <= Parameters.HandThumbDefectMaxShortLongLengthRatio && shortLongLengthRatio >= Parameters.HandThumbDefectMinShortLongLengthRatio);
         }
 
+        /// <summary>
+        /// Tests if this defect is caused by a finger.
+        /// </summary>
+        /// <param name="finger">the finger maybe causing the defect</param>
+        /// <returns>true iff this defect is caused by finger</returns>
         public bool isCausedByFinger(Finger finger) {
             return (OuterLineSegment.intersectsWith(finger.LineSegment));
         }

+ 48 - 0
bbiwarg/Utility/CoordinateConverter.cs

@@ -6,14 +6,43 @@ using System.Threading.Tasks;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// Converts between 2d and 3d coordinates.
+    /// </summary>
     public class CoordinateConverter
     {
+        /// <summary>
+        /// size of the image the coordinates are from
+        /// </summary>
         private ImageSize imageSize;
+
+        /// <summary>
+        /// the horizontal field of view angle
+        /// </summary>
         private float hfov;
+
+        /// <summary>
+        /// the vertical field of view angle
+        /// </summary>
         private float vfov;
+
+        /// <summary>
+        /// tangens of hfov / 2
+        /// </summary>
         private float hRatio;
+
+        /// <summary>
+        /// tanges of vfov / 2
+        /// </summary>
         private float vRatio;
 
+
+        /// <summary>
+        /// Constructs a CoordinateConverter.
+        /// </summary>
+        /// <param name="imageSize">size of the image the coordinates are from</param>
+        /// <param name="hfov">horizontal field of view angle</param>
+        /// <param name="vfov">vertical field of view angle</param>
         public CoordinateConverter(ImageSize imageSize, float hfov, float vfov)
         {
             this.imageSize = imageSize;
@@ -24,10 +53,23 @@ namespace bbiwarg.Utility
             vRatio = (float)Math.Tan(vfov / 2);
         }
 
+        /// <summary>
+        /// Converts a point with a depth to a 3d position.
+        /// </summary>
+        /// <param name="p">the point</param>
+        /// <param name="depth">the depth</param>
+        /// <returns>the 3d position</returns>
         public Vector3D convertCoordinate2Dto3D(Vector2D p, float depth) {
             return convertCoordinate2Dto3D(p.X, p.Y, depth);
         }
 
+        /// <summary>
+        /// Converts a position with a depth to a 3d position.
+        /// </summary>
+        /// <param name="x">x coordinate of the position</param>
+        /// <param name="y">y cooridnate of the position</param>
+        /// <param name="depth">the depth</param>
+        /// <returns>the 3d position</returns>
         public Vector3D convertCoordinate2Dto3D(float x, float y, float depth)
         {
             float deltaX = 2 * ((x / imageSize.Width) - 0.5f);
@@ -46,6 +88,12 @@ namespace bbiwarg.Utility
             return new Vector3D(x3, y3, z3);
         }
 
+        /// <summary>
+        /// Converts the length of a 3d linesegment parallel to the camera at the given depth to the length of the linesegment in 2d.
+        /// </summary>
+        /// <param name="length">3d length of the linesegment</param>
+        /// <param name="depth">depth of the linesegment</param>
+        /// <returns>2d length of the linesegment</returns>
         public float convertLength3Dto2D(float length, float depth) {
             float fullLengthX = (float)(2 * Math.Cos(hfov / 2) * depth);
             float fullLengthY = (float)(2 * Math.Cos(vfov / 2) * depth);

+ 38 - 0
bbiwarg/Utility/ImageSize.cs

@@ -7,24 +7,62 @@ using System.Threading.Tasks;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// Manages the size of a image.
+    /// </summary>
     public class ImageSize
     {
+        /// <summary>
+        /// image width
+        /// </summary>
         public int Width {get; private set;}
+
+        /// <summary>
+        /// image height
+        /// </summary>
         public int Height {get; private set;}
+
+        /// <summary>
+        /// position in the image with maximum x and y values
+        /// </summary>
         public Vector2D MaxPixel {get; private set;}
+
+        /// <summary>
+        /// the length of the longer image diagonal
+        /// </summary>
         public float DiagonalLength { get { return MaxPixel.Length; } }
+
+        /// <summary>
+        /// number of pixels in the image
+        /// </summary>
         public int NumPixels { get { return Width * Height; } }
 
+
+        /// <summary>
+        /// Constructs a ImageSize.
+        /// </summary>
+        /// <param name="width">image width</param>
+        /// <param name="height">image height</param>
         public ImageSize(int width, int height) {
             Width = width;
             Height = height;
             MaxPixel = new Vector2D(width - 1, height - 1);
         }
 
+        /// <summary>
+        /// Computes an absolute point in the image.
+        /// </summary>
+        /// <param name="relativePoint">realtive point (x and y in [0,1])</param>
+        /// <returns>absolute point</returns>
         public Vector2D getAbsolutePoint(Vector2D relativePoint) {
             return relativePoint.scale(MaxPixel);
         }
 
+        /// <summary>
+        /// Computes a relative point in the image.
+        /// </summary>
+        /// <param name="absolutePoint">absolute point in the image</param>
+        /// <returns>realtive point (x and y in [0,1])</returns>
         public Vector2D getRelativePoint(Vector2D absolutePoint) {
             return new Vector2D(absolutePoint.X / Width, absolutePoint.Y / Height);
         }

+ 60 - 2
bbiwarg/Utility/Kalman2DPositionFilter.cs

@@ -9,14 +9,49 @@ using Emgu.CV.Structure;
 
 namespace bbiwarg.Utility
 {
+    /// <summary>
+    /// Filter used to smooth a series of 2d positions.
+    /// </summary>
     class Kalman2DPositionFilter
     {
+        /// <summary>
+        /// the emgu kalman filter
+        /// </summary>
         private Kalman kalman;
-        private float mXX, mXY, mYY, processNoiseFactor;
+
+        /// <summary>
+        /// xx entry for the measurement noise covariance matrix
+        /// </summary>
+        private float mXX;
+
+        /// <summary>
+        /// xy and yx entry for the measurement noise covariance matrix
+        /// </summary>
+        private float mXY;
+
+        /// <summary>
+        /// yy entry for the measurement noise covariance matrix
+        /// </summary> 
+        private float mYY;
+        
+        /// <summary>
+        /// value used for all entries in the process noise covariance matrix
+        /// </summary>
+        private float processNoiseFactor;
+        
+
+        /// <summary>
+        /// number of measurements per second
+        /// </summary>
         private float fps;
 
+
+        /// <summary>
+        /// true iff the kalman filter is initialized
+        /// </summary>
         public bool Initialized { get; private set; }
 
+
         // state: x, y, v_x, v_y
         //   x: current x position
         //   y: current y position
@@ -24,6 +59,14 @@ namespace bbiwarg.Utility
         // v_y: velocity in y direction
         // a_x: acceleration in x direction
         // a_y: acceleration in y direction
+        /// <summary>
+        /// Creates a Kalman2DPositionFilter.
+        /// </summary>
+        /// <param name="mXX">xx entry for the measurement noise covariance matrix</param>
+        /// <param name="mXY">xy and yx entry for the measurement noise covariance matrix</param>
+        /// <param name="mYY">yy entry for the measurement noise covariance matrix</param>
+        /// <param name="processNoiseFactor">value used for all entries in the process noise covariance matrix</param>
+        /// <param name="fps">number of measurements per second</param>
         public Kalman2DPositionFilter(float mXX, float mXY, float mYY, float processNoiseFactor = 1.0e-4f, int fps = 30)
         {
             this.mXX = mXX;
@@ -34,6 +77,9 @@ namespace bbiwarg.Utility
             reset();
         }
 
+        /// <summary>
+        /// Resets the kalman filter.
+        /// </summary>
         public void reset()
         {
             // 6 state variables and 2 measurements (0 controls)
@@ -77,6 +123,10 @@ namespace bbiwarg.Utility
             Initialized = false;
         }
 
+        /// <summary>
+        /// Sets the initial position.
+        /// </summary>
+        /// <param name="initialPosition">initial position</param>
         public void setInitialPosition(Vector2D initialPosition)
         {
             // initial state (x, y, v_x, v_y)
@@ -86,13 +136,21 @@ namespace bbiwarg.Utility
             Initialized = true;
         }
 
+        /// <summary>
+        /// Computes a prediction for the next position based on the previous positions.
+        /// </summary>
+        /// <returns>prediction for the next position</returns>
         public Vector2D getPrediction()
         {
             Matrix<float> predicton = kalman.Predict();
             return new Vector2D(predicton[0, 0], predicton[1, 0]);
         }
 
-        // updates the filter and returns the corrected position
+        /// <summary>
+        /// Computes a smoothed position for a measurement and updates the filter.
+        /// </summary>
+        /// <param name="rawPosition">the measurement</param>
+        /// <returns>the smoothed position</returns>
         public Vector2D getCorrectedPosition(Vector2D rawPosition)
         {
             Matrix<float> rawPositionMatrix = new Matrix<float>(new float[,]