Bladeren bron

finger direction now gets fixed by fingertracker

Alexander Hendrich 10 jaren geleden
bovenliggende
commit
a2d4c14b3f

+ 1 - 0
bbiwarg/Constants.cs

@@ -60,6 +60,7 @@ namespace bbiwarg
         public static readonly int FingerSliceOverlapFactor = 2;
         public static readonly int FingerCrippleOutFactor = 8;
         public static readonly int FingerCrippleOutMinDifference = 20;
+        public static readonly int FingerNumDirectionsForReverseCheck = 20;
 
         // finger tracking
         public static readonly int FingerNumFramesDetectedUntilTracked = 5;

+ 5 - 1
bbiwarg/Recognition/FingerRecognition/Finger.cs

@@ -24,7 +24,7 @@ namespace bbiwarg.Recognition.FingerRecognition
         public Vector2D HandDirection { get { return SliceTrail.getEndDirection(); } }
         public LineSegment2D LineSegment { get { return SliceTrail.LineSegment; } }
         public FingerSliceTrail SliceTrail { get; private set; }
-        public Contour<Point> Contour { get { return SliceTrail.getContour(); } }
+        public Contour<Point> Contour { get { return SliceTrail.Contour; } }
         public Hand Hand { get; private set; }
         public TouchEvent TouchEvent { get; private set; }
 
@@ -34,6 +34,10 @@ namespace bbiwarg.Recognition.FingerRecognition
             SliceTrail = sliceTrail;
         }
 
+        public void reverse() {
+            SliceTrail.reverse();
+        }
+
         public void setHand(Hand hand)
         {
             Hand = hand;

+ 10 - 2
bbiwarg/Recognition/FingerRecognition/FingerSlice.cs

@@ -9,11 +9,14 @@ namespace bbiwarg.Recognition.FingerRecognition
 {
     class FingerSlice
     {
+        private LineSegment2D lineSegment;
+        private bool lineSegmentUpToDate;
+
         public Vector2D Start { get; private set; }
         public Vector2D Mid { get; private set; }
         public Vector2D End { get; private set; }
+        public LineSegment2D LineSegment { get { if (!lineSegmentUpToDate) updateLineSegment(); return lineSegment; } }
         public Vector2D Direction { get { return LineSegment.Direction; } }
-        public LineSegment2D LineSegment { get; private set; }
         public float Length { get { return LineSegment.Length; } }
 
         public FingerSlice(Vector2D start, Vector2D end)
@@ -21,7 +24,12 @@ namespace bbiwarg.Recognition.FingerRecognition
             Start = start;
             End = end;
             Mid = (start + end) / 2;
-            LineSegment = new LineSegment2D(Start, End);
+            lineSegmentUpToDate = false;
+        }
+
+        private void updateLineSegment()
+        {
+            lineSegment = new LineSegment2D(Start, End);
         }
 
     }

+ 31 - 33
bbiwarg/Recognition/FingerRecognition/FingerSliceTrail.cs

@@ -12,35 +12,32 @@ namespace bbiwarg.Recognition.FingerRecognition
     class FingerSliceTrail
     {
         private List<FingerSlice> slices;
-        private List<Point> pointsA;
-        private List<Point> pointsB;
+        private LineSegment2D lineSegment;
+        private Contour<Point> contour;
+        private bool lineSegmentUpToDate;
+        private bool contourUpToDate;
+
         public FingerSlice StartSlice { get { return slices[0]; } }
         public FingerSlice MidSlice { get { return slices[NumSlices / 2]; } }
         public FingerSlice EndSlice { get { return slices[slices.Count - 1]; } }
         public FingerSlice this[int index] { get { return slices[index]; } }
         public int NumSlices { get { return slices.Count; } }
-        public LineSegment2D LineSegment { get; private set; }
+        public LineSegment2D LineSegment { get { if (!lineSegmentUpToDate) updateLineSegment(); return lineSegment; } }
+        public Contour<Point> Contour { get { if (!contourUpToDate) updateContour(); return contour; } }
 
         public FingerSliceTrail(FingerSlice slice)
         {
             slices = new List<FingerSlice>();
-            pointsA = new List<Point>();
-            pointsB = new List<Point>();
             addSlice(slice);
+            lineSegmentUpToDate = false;
+            contourUpToDate = false;
         }
 
         public void addSlice(FingerSlice slice)
         {
             slices.Add(slice);
-            pointsA.Add(slice.Start + Constants.FingerContourMargin * slice.Direction.getInverse());
-            pointsB.Add(slice.End + Constants.FingerContourMargin * slice.Direction);
-            pointsA.Add(slice.Start);
-            createLineSegment();
-        }
-
-        private void createLineSegment()
-        {
-            LineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid);
+            lineSegmentUpToDate = false;
+            contourUpToDate = false;
         }
 
         public Vector2D getStartDirection()
@@ -58,40 +55,41 @@ namespace bbiwarg.Recognition.FingerRecognition
         public void removeFirstSlices(int numSlices)
         {
             slices.RemoveRange(0, numSlices);
-            pointsA.RemoveRange(0, numSlices);
-            pointsB.RemoveRange(0, numSlices);
-            createLineSegment();
+            lineSegmentUpToDate = false;
+            contourUpToDate = false;
         }
 
         public void reverse()
         {
             slices.Reverse();
-            pointsA.Reverse();
-            pointsB.Reverse();
-
-            List<Point> dummy = pointsA;
-            pointsA = pointsB;
-            pointsB = dummy;
+            lineSegmentUpToDate = false;
+            contourUpToDate = false;
+        }
 
-            createLineSegment();
+        private void updateLineSegment()
+        {
+            lineSegment = new LineSegment2D(EndSlice.Mid, StartSlice.Mid);
         }
 
+        private void updateContour()
+        {
+            List<Point> pointsA = new List<Point>();
+            List<Point> pointsB = new List<Point>();
 
+            foreach (FingerSlice slice in slices)
+            {
+                pointsA.Add(slice.Start + Constants.FingerContourMargin * slice.Direction.getInverse());
+                pointsB.Add(slice.End + Constants.FingerContourMargin * slice.Direction);
+            }
 
-        public Contour<Point> getContour()
-        {
-            pointsA.Reverse();
-            List<Point> points = new List<Point>();
-            points.AddRange(pointsA);
-            points.AddRange(pointsB);
             pointsA.Reverse();
+            pointsA.AddRange(pointsB);
 
-            Contour<Point> contour = new Contour<Point>(new MemStorage());
-            foreach (Point p in points)
+            contour = new Contour<Point>(new MemStorage());
+            foreach (Point p in pointsA)
             {
                 contour.Push(p);
             }
-            return contour;
         }
     }
 }

+ 33 - 8
bbiwarg/Recognition/FingerRecognition/TrackedFinger.cs

@@ -12,6 +12,7 @@ namespace bbiwarg.Recognition.FingerRecognition
     {
         private Kalman2DPositionFilter tipPointKalman;
         private Kalman2DPositionFilter handPointKalman;
+        private List<Vector2D> lastRawDirections;
 
         public Vector2D TipPointPrediction { get { return tipPointKalman.getPrediction(); } }
         public Vector2D HandPointPrediction { get { return handPointKalman.getPrediction(); } }
@@ -23,37 +24,61 @@ namespace bbiwarg.Recognition.FingerRecognition
             tipPointKalman.setInitialPosition(detectedFinger.TipPoint);
             handPointKalman = new Kalman2DPositionFilter(Constants.FingermXX, Constants.FingermXY, Constants.FingermYY);
             handPointKalman.setInitialPosition(detectedFinger.HandPoint);
+            lastRawDirections = new List<Vector2D>();
 
             logStateChange();
         }
 
-        public override void updateFrame(Finger detectedObject)
+        public override void updateFrame(Finger detectedFinger)
         {
-            base.updateFrame(detectedObject);
+            base.updateFrame(detectedFinger);
 
             if (NumFramesInCurrentState == 1)
                 logStateChange();
 
-            if (detectedObject != null)
+            if (detectedFinger != null)
             {
-                tipPointKalman.getCorrectedPosition(detectedObject.TipPoint);
-                handPointKalman.getCorrectedPosition(detectedObject.HandPoint);
+                Vector2D rawDirection = detectedFinger.Direction;
+                if (shouldFingerBeReversed(detectedFinger))
+                    detectedFinger.reverse();
+
+                tipPointKalman.getCorrectedPosition(detectedFinger.TipPoint);
+                handPointKalman.getCorrectedPosition(detectedFinger.HandPoint);
+                lastRawDirections.Add(rawDirection);
+                if (lastRawDirections.Count == Constants.FingerNumDirectionsForReverseCheck)
+                    lastRawDirections.RemoveAt(0);
             }
         }
 
-        public override float getSimilarity(Finger detectedFinger)
+        public override float calculateSimilarity(Finger detectedFinger)
         {
+            Vector2D tip, hand;
+            if (shouldFingerBeReversed(detectedFinger))
+            {
+                tip = detectedFinger.HandPoint;
+                hand = detectedFinger.TipPoint;
+            }
+            else {
+                tip = detectedFinger.TipPoint;
+                hand = detectedFinger.HandPoint;
+            }
+
             //tip position
-            float tipPointDistance = detectedFinger.TipPoint.getDistanceTo(TipPointPrediction);
+            float tipPointDistance = tip.getDistanceTo(TipPointPrediction);
             float tipPointSimilarity = Math.Max(0, 1 - tipPointDistance / Constants.ImageDiagonalLength);
 
             //hand position
-            float handPointDistance = detectedFinger.HandPoint.getDistanceTo(HandPointPrediction);
+            float handPointDistance = hand.getDistanceTo(HandPointPrediction);
             float handPointSimilarity = Math.Max(0, 1 - handPointDistance / Constants.ImageDiagonalLength);
 
             return tipPointSimilarity * handPointSimilarity;
         }
 
+        private bool shouldFingerBeReversed(Finger detectedFinger) {
+            Vector2D meanDirection = Vector2D.mean(lastRawDirections);
+            return (meanDirection.getAngleBetween(detectedFinger.Direction) > Math.PI / 4);
+        }
+
         private void logStateChange()
         {
             String stateAsString = CurrentState.ToString().ToLower();

+ 1 - 1
bbiwarg/Recognition/TouchRecognition/TrackedTouchEvent.cs

@@ -77,7 +77,7 @@ namespace bbiwarg.Recognition.TouchRecognition
 
         }
 
-        public override float getSimilarity(TouchEvent detectedTouchEvent)
+        public override float calculateSimilarity(TouchEvent detectedTouchEvent)
         {
             //finger similarity
             float fingerSimilarity = (fingerID == detectedTouchEvent.Finger.TrackID) ? 1 : 0;

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

@@ -42,7 +42,7 @@ namespace bbiwarg.Recognition.Tracking
             NumFramesInCurrentState = 1;
         }
 
-        public abstract float getSimilarity(T detectedObject);
+        public abstract float calculateSimilarity(T detectedObject);
 
         public virtual void updateFrame(T detectedObject)
         {

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

@@ -78,7 +78,7 @@ namespace bbiwarg.Recognition.Tracking
 
             foreach (TrackedT trackedObject in TrackedObjects) {
                 foreach (T detectedObject in detectedObjects) {
-                    float similarityValue = trackedObject.getSimilarity(detectedObject);
+                    float similarityValue = trackedObject.calculateSimilarity(detectedObject);
                     Similarity<T, TrackedT> similarity = new Similarity<T,TrackedT>(trackedObject, detectedObject, similarityValue);
                     if (similarity.Value > minSimilarity)
                         similarities.Add(similarity);