Browse Source

fixed bug in fingerDirection (caused by fitted direction)

Alexander Hendrich 10 years ago
parent
commit
4d12e7ecc9

+ 2 - 5
bbiwarg/Images/EdgeImage.cs

@@ -57,7 +57,7 @@ namespace bbiwarg.Images
             RoughImage.FillConvexPoly(polygon, new Gray(0));
         }
 
-        public Vector2D findNextEdge(Vector2D start, Vector2D direction, int maxSearchSize = 0, bool roughEdge = true, bool returnNullIfNoEdgeFound = true)
+        public Vector2D findNextEdge(Vector2D start, Vector2D direction, int maxSearchSize = 0, bool roughEdge = true)
         {
             Vector2D maxGrow = (Parameters.ImageMaxPixel - start) / direction;
             Vector2D maxDecline = start / direction.getAbsolute();
@@ -94,10 +94,7 @@ namespace bbiwarg.Images
                 }
             }
 
-            if (returnNullIfNoEdgeFound)
-                return null;
-            else
-                return end;
+            return null;
         }
 
         public EdgeImage copy()

+ 3 - 1
bbiwarg/InputHandler.cs

@@ -244,7 +244,7 @@ namespace bbiwarg
             OutputImages[0].drawImage((depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image, Parameters.DepthImageColor);
             foreach (Finger f in fingerTracker.Fingers)
             {
-                OutputImages[0].fillCircle(f.TipPoint.IntX, f.TipPoint.IntY, 4, Parameters.FingerTipColor);
+                OutputImages[0].fillCircle(f.TipPoint.IntX, f.TipPoint.IntY, 5, Parameters.FingerTipColor);
             }
 
             foreach (TrackedFinger tf in fingerTracker.TrackedObjects)
@@ -253,6 +253,8 @@ namespace bbiwarg
                 {
                     OutputImages[0].fillCircle(tf.TipPointPrediction.IntX, tf.TipPointPrediction.IntY, 3, Parameters.FingerPointsPredictionColor);
                     OutputImages[0].fillCircle(tf.HandPointPrediction.IntX, tf.HandPointPrediction.IntY, 3, Parameters.FingerPointsPredictionColor);
+                    Vector2D mid = (tf.TipPointPrediction+tf.HandPointPrediction) /2 ;
+                    OutputImages[0].drawLineSegment(new Utility.LineSegment2D(mid, mid + Parameters.FingerTrackerNumDirectionsForMeanDirection*tf.MeanDirection), Parameters.FingerMeanDirectionColor);
                 }
             }
 

+ 4 - 4
bbiwarg/Parameters.cs

@@ -56,8 +56,8 @@ namespace bbiwarg
         public static readonly int DepthImageDepthRange = 200; // <255
 
         // edge image
-        public static readonly int EdgeImageCannyStartThreshold = 60;
-        public static readonly int EdgeImageCannyLinkingThreshold = 40;
+        public static readonly int EdgeImageCannyStartThreshold = 80;
+        public static readonly int EdgeImageCannyLinkingThreshold = 60;
         public static readonly int EdgeImageCannySize = 3;
         public static readonly int EdgeImageRoughNumDilationIterations = 1;
 
@@ -66,7 +66,6 @@ namespace bbiwarg
         public static readonly int FingerMaxGapCounter = 5;
         public static readonly int FingerMaxSliceDifferencePerStep = 5;
         public static readonly int FingerMinNumSlices = 25 / FingerStepSize;
-        public static readonly int FingerNumSlicesForDirectionDetection = FingerMinNumSlices / 4;
         public static readonly int FingerMaxWidth = 30;
         public static readonly int FingerMinWidth = 2;
         public static readonly int FingerRemoveNumSlicesForCorrection = 5;
@@ -83,7 +82,7 @@ namespace bbiwarg
         public static readonly float FingermXX = 0.00005f;
         public static readonly float FingermXY = 0.0f;
         public static readonly float FingermYY = 0.00005f;
-        public static readonly int FingerTrackerNumDirectionsForReverseCheck = 20;
+        public static readonly int FingerTrackerNumDirectionsForMeanDirection = 10;
 
         // hand detection
         public static readonly int HandNumColors = 3;
@@ -160,6 +159,7 @@ namespace bbiwarg
         public static readonly Color FingerContourColor = Color.Red;
         public static readonly Color FingerIDColor = Color.White;
         public static readonly Color FingerPointsPredictionColor = Color.Yellow;
+        public static readonly Color FingerMeanDirectionColor = Color.Red;
 
         public static readonly Color TouchEventDetectedColor = ColorDetected;
         public static readonly Color TouchEventTrackedColor = ColorTracked;

+ 5 - 18
bbiwarg/Recognition/FingerRecognition/FingerDetector.cs

@@ -163,7 +163,7 @@ namespace bbiwarg.Recognition.FingerRecognition
         {
             Vector2D searchStart = start + Parameters.FingerContourMargin * direction;
             Vector2D end = edgeImageAdapted.findNextEdge(searchStart, direction, Parameters.FingerMaxWidth);
-            if (end == null) 
+            if (end == null)
                 return null;
 
             return getFingerSlice(start, end);
@@ -215,25 +215,12 @@ namespace bbiwarg.Recognition.FingerRecognition
 
         private FingerSliceTrail orderTrailTipToHand(FingerSliceTrail trail)
         {
-            int numSlicesForDirectionDetection = Parameters.FingerNumSlicesForDirectionDetection;
-            int maxIndex = trail.NumSlices - 1;
-            float sumStart = 0;
-            float sumEnd = 0;
+            float startLength = trail.StartSlice.Length;
+            float endLength = trail.EndSlice.Length;
 
-            for (int i = 0; i < numSlicesForDirectionDetection; i++)
-            {
-                sumStart += trail[i].Length;
-                sumEnd += trail[maxIndex - i].Length;
-            }
-
-
-            float avergaeStart = sumStart / numSlicesForDirectionDetection;
-            float averageEnd = sumEnd / numSlicesForDirectionDetection;
-
-            //check direction
-            if (avergaeStart > averageEnd)
+            if (startLength > endLength)
                 trail.reverse();
-
+            
             return trail;
         }
     }

+ 5 - 6
bbiwarg/Recognition/FingerRecognition/FingerSliceTrail.cs

@@ -81,11 +81,7 @@ namespace bbiwarg.Recognition.FingerRecognition
 
         private void updateLineSegment()
         {
-            //lineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid);
-            float length_2 = 0.5f * (EndSlice.Mid.getDistanceTo(StartSlice.Mid));
-            Vector2D p1 = MidSlice.Mid + length_2 * FittedDirection;
-            Vector2D p2 = MidSlice.Mid - length_2 * FittedDirection;
-            lineSegment = new LineSegment2D(p1, p2);
+            lineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid);
 
             lineSegmentUpToDate = true;
         }
@@ -98,7 +94,10 @@ namespace bbiwarg.Recognition.FingerRecognition
 
             PointF pointOnLine, direction;
             PointCollection.Line2DFitting(midPoints.ToArray(), Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_FAIR, out direction, out pointOnLine);
-            fittedDirection = new Vector2D(direction).normalize().getInverse();
+            fittedDirection = new Vector2D(direction).normalize();
+
+            if (fittedDirection.isInOppositeDirection(LineSegment.Direction))
+                fittedDirection = fittedDirection.getInverse();
 
             fittedDirectionUpToDate = true;
         }

+ 7 - 4
bbiwarg/Recognition/FingerRecognition/TrackedFinger.cs

@@ -16,6 +16,7 @@ namespace bbiwarg.Recognition.FingerRecognition
 
         public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
         public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
+        public Vector2D MeanDirection { get { return Vector2D.mean(lastRawDirections); } }
 
         public TrackedFinger(int id, Finger detectedFinger, int numFramesDetectedUntilTracked, int numFramesLostUntilDeleted)
             : base(id, detectedFinger, numFramesDetectedUntilTracked, numFramesLostUntilDeleted)
@@ -45,7 +46,7 @@ namespace bbiwarg.Recognition.FingerRecognition
                 tipPointKalman.getCorrectedPosition(detectedFinger.TipPoint);
                 handPointKalman.getCorrectedPosition(detectedFinger.HandPoint);
                 lastRawDirections.Add(rawDirection);
-                if (lastRawDirections.Count == Parameters.FingerTrackerNumDirectionsForReverseCheck)
+                if (lastRawDirections.Count == Parameters.FingerTrackerNumDirectionsForMeanDirection)
                     lastRawDirections.RemoveAt(0);
             }
         }
@@ -58,7 +59,8 @@ namespace bbiwarg.Recognition.FingerRecognition
                 tip = detectedFinger.HandPoint;
                 hand = detectedFinger.TipPoint;
             }
-            else {
+            else
+            {
                 tip = detectedFinger.TipPoint;
                 hand = detectedFinger.HandPoint;
             }
@@ -69,9 +71,10 @@ namespace bbiwarg.Recognition.FingerRecognition
             return tipPointSimilarity * handPointSimilarity;
         }
 
-        private bool shouldFingerBeReversed(Finger detectedFinger) {
+        private bool shouldFingerBeReversed(Finger detectedFinger)
+        {
             Vector2D meanDirection = Vector2D.mean(lastRawDirections);
-            return (meanDirection.getAngleBetween(detectedFinger.Direction) > Math.PI / 4);
+            return meanDirection.isInOppositeDirection(detectedFinger.Direction);
         }
 
         private void logStateChange()

+ 21 - 8
bbiwarg/Utility/Vector2D.cs

@@ -50,6 +50,11 @@ namespace bbiwarg.Utility
             return (float)Math.Acos(dotProduct(vector) / (Length * vector.Length));
         }
 
+        public bool isInOppositeDirection(Vector2D vector)
+        {
+            return (getAngleBetween(vector) > Math.PI / 2);
+        }
+
         public float dotProduct(Vector2D vector)
         {
             return X * vector.X + Y * vector.Y;
@@ -74,7 +79,8 @@ namespace bbiwarg.Utility
             return (minX <= X && X <= maxX && minY <= Y && Y <= maxY);
         }
 
-        public bool isInBound() {
+        public bool isInBound()
+        {
             return isInBound(Vector2D.Zero, Parameters.ImageMaxPixel);
         }
 
@@ -83,7 +89,8 @@ namespace bbiwarg.Utility
             return (X >= topLeft.X && X <= bottomRight.X && Y >= topLeft.Y && Y <= bottomRight.Y);
         }
 
-        public Vector2D moveInBound(Vector2D inBoundDirection) {
+        public Vector2D moveInBound(Vector2D inBoundDirection)
+        {
             return moveInBound(Vector2D.Zero, Parameters.ImageMaxPixel, inBoundDirection);
         }
 
@@ -121,7 +128,8 @@ namespace bbiwarg.Utility
             return new Vector2D(Math.Abs(X), Math.Abs(Y));
         }
 
-        public Vector2D copy() {
+        public Vector2D copy()
+        {
             return new Vector2D(X, Y);
         }
 
@@ -161,12 +169,17 @@ namespace bbiwarg.Utility
 
         public static Vector2D mean(List<Vector2D> vectors)
         {
-            Vector2D meanVector = new Vector2D(0, 0);
+            Vector2D sumVector = Vector2D.sum(vectors);
+            return sumVector / vectors.Count;
+        }
+
+        public static Vector2D sum(List<Vector2D> vectors)
+        {
+            Vector2D sumVector = new Vector2D(0, 0);
             foreach (Vector2D vector in vectors)
-            {
-                meanVector += vector;
-            }
-            return meanVector / vectors.Count;
+                sumVector += vector;
+
+            return sumVector;
         }
 
         public static implicit operator PointF(Vector2D vec)