Browse Source

rewritten finger/fingerSlice/fingerSliceTrail

Alexander Hendrich 10 years ago
parent
commit
a9e5e9e65c

+ 1 - 1
bbiwarg/Constants.cs

@@ -10,7 +10,7 @@ namespace bbiwarg
     class Constants
     {
         // BBIWARG
-        public static readonly bool OutputTimerEnabled = true;
+        public static readonly bool OutputTimerEnabled = false;
         public static readonly int OutputNumImages = 5;
         public static readonly int OutputNumImagesPerRow = 3;
         public static readonly float OutputScaleFactor = 1f; // output window size is scaled by this factor (from necessary size for images)

+ 6 - 26
bbiwarg/Detectors/FingerDetection/Finger.cs

@@ -12,42 +12,22 @@ namespace bbiwarg.Detectors.FingerDetection
 {
     class Finger
     {
-        public Vector2D TipPoint { get { return SliceTrail.Start.Mid; } }
-        public Vector2D HandPoint { get { return SliceTrail.End.Mid; } }
+        public Vector2D TipPoint { get { return SliceTrail.StartSlice.Mid; } }
+        public Vector2D HandPoint { get { return SliceTrail.EndSlice.Mid; } }
+        public Vector2D Direction { get { return LineSegment.Direction; } }
         public LineSegment2D LineSegment { get { return SliceTrail.LineSegment; } }
         public FingerSliceTrail SliceTrail { get; private set; }
+        public Contour<Point> Contour { get { return SliceTrail.getContour(); } }
 
         public Finger(FingerSliceTrail sliceTrail)
         {
             //check direction
-            if (sliceTrail.Start.Length > sliceTrail.End.Length)
-                sliceTrail.Slices.Reverse();
+            if (sliceTrail.StartSlice.Length > sliceTrail.EndSlice.Length)
+                sliceTrail.reverse();
 
             SliceTrail = sliceTrail;
         }
 
-        public Contour<Point> getContour()
-        {
-            List<Point> pointsA = new List<Point>();
-            List<Point> pointsB = new List<Point>();
-            foreach (FingerSlice slice in SliceTrail.Slices)
-            {
-                Vector2D direction = (slice.End - slice.Start).normalize();
-                pointsA.Add(slice.Start - Constants.FingerContourMargin * direction);
-                pointsB.Add(slice.End + Constants.FingerContourMargin * direction);
-            }
-
-            pointsA.Reverse();
-            pointsA.AddRange(pointsB);
-
-            Contour<Point> contour = new Contour<Point>(new MemStorage());
-            foreach (Point p in pointsA)
-            {
-                contour.Push(p);
-            }
-            return contour;
-        }
-
         //TODO: redo (not use similarity but actual distances and angle instead)
         public float getSimilarity(Finger compareFinger)
         {

+ 16 - 13
bbiwarg/Detectors/FingerDetection/FingerDetector.cs

@@ -23,6 +23,7 @@ namespace bbiwarg.Detectors.FingerDetection
 
         public FingerDetector(DepthImage depthImage, EdgeImage edgeImage, OutputImage outputImage)
         {
+            Console.WriteLine("---");
             this.depthImage = depthImage;
             this.edgeImageOriginal = edgeImage;
             this.edgeImageAdapted = edgeImage.copy();
@@ -100,10 +101,10 @@ namespace bbiwarg.Detectors.FingerDetection
 
                     if (trail.NumSlices > Constants.FingerMinNumSlices / 2)
                     {
-                        trail.Slices.RemoveRange(0, Constants.FingerRemoveNumSlicesForCorrection);
-                        trail.Slices.Reverse();
+                        trail.removeFirstSlices(Constants.FingerRemoveNumSlicesForCorrection);
+                        trail.reverse();
                         trail = expandTrail(trail, true);
-                        trail.Slices.Reverse();
+                        trail.reverse();
                         return trail;
                     }
                 }
@@ -119,12 +120,12 @@ namespace bbiwarg.Detectors.FingerDetection
             int maxY = depthImage.Height - 1;
 
             Vector2D currentDirection = trail.getEndDirection();
-            Vector2D currentPosition = trail.End.Mid + Constants.FingerStepSize * currentDirection;
+            Vector2D currentPosition = trail.EndSlice.Mid + Constants.FingerStepSize * currentDirection;
 
             int gapCounter = 0;
             int numSlices = trail.NumSlices;
 
-            FingerSlice lastSlice = trail.End;
+            FingerSlice lastSlice = trail.EndSlice;
             FingerSlice nextSlice;
 
             while (currentPosition.isWithin(0, 0, maxX, maxY) && gapCounter <= Math.Min(numSlices, Constants.FingerMaxGapCounter))
@@ -255,9 +256,11 @@ namespace bbiwarg.Detectors.FingerDetection
             //add finger
             if (!isCrippleFinger(finger))
                 Fingers.Add(finger);
+            else
+                Console.WriteLine("cripple");
 
             //remove edges around detected finger to improve performance
-            edgeImageAdapted.removeEdgesInsidePolygon(finger.getContour().ToArray());
+            edgeImageAdapted.removeEdgesInsidePolygon(finger.Contour.ToArray());
         }
 
         private bool isCrippleFinger(Finger finger)
@@ -265,8 +268,8 @@ namespace bbiwarg.Detectors.FingerDetection
             int maxX = depthImage.Width - 1;
             int maxY = depthImage.Height - 1;
 
-            FingerSlice midSlice = finger.SliceTrail.Slices[finger.SliceTrail.NumSlices / 2];
-            Vector2D direction = midSlice.LineSegment.Line.Direction;
+            FingerSlice midSlice = finger.SliceTrail.MidSlice;
+            Vector2D direction = midSlice.Direction;
             Vector2D out1 = (midSlice.Start - Constants.FingerCrippleOutFactor * direction).moveInBound(0, 0, maxX, maxY);
             Vector2D out2 = (midSlice.End + Constants.FingerCrippleOutFactor * direction).moveInBound(0, 0, maxX, maxY);
 
@@ -300,8 +303,8 @@ namespace bbiwarg.Detectors.FingerDetection
             int maxX = depthImage.Width - 2;
             int maxY = depthImage.Height - 2;
 
-            FingerSlice start = trail.Start;
-            FingerSlice end = trail.End;
+            FingerSlice start = trail.StartSlice;
+            FingerSlice end = trail.EndSlice;
 
             Vector2D direction = (end.Mid - start.Mid).normalize();
 
@@ -319,7 +322,7 @@ namespace bbiwarg.Detectors.FingerDetection
 
             if (startOutLength <= endOutLength)
             {
-                trail.Slices.Reverse();
+                trail.reverse();
                 outputImage.drawLineSegment(startOutSlice.LineSegment, Constants.FingerHandOutSliceColor);
                 outputImage.drawLineSegment(endOutSlice.LineSegment, Constants.FingerTipOutSliceColor);
             }
@@ -345,10 +348,10 @@ namespace bbiwarg.Detectors.FingerDetection
             FingerSliceTrail trail = finger.SliceTrail;
             for (int i = 0; i < trail.NumSlices; i++)
             {
-                outputImage.drawLineSegment(trail.Slices[i].LineSegment, Constants.FingerSliceColor);
+                outputImage.drawLineSegment(trail[i].LineSegment, Constants.FingerSliceColor);
             }
             outputImage.drawLineSegment(finger.LineSegment, Constants.FingerDetectedColor);
-            outputImage.drawContour(finger.getContour(), Constants.FingerContourColor, 1);
+            outputImage.drawContour(finger.Contour, Constants.FingerContourColor, 1);
         }
     }
 }

+ 2 - 2
bbiwarg/Detectors/FingerDetection/FingerSlice.cs

@@ -12,8 +12,9 @@ namespace bbiwarg.Detectors.FingerDetection
         public Vector2D Start { get; private set; }
         public Vector2D Mid { get; private set; }
         public Vector2D End { get; private set; }
+        public Vector2D Direction { get { return LineSegment.Direction; } }
         public LineSegment2D LineSegment { get; private set; }
-        public float Length { get; private set; }
+        public float Length { get { return LineSegment.Length; } }
 
         public FingerSlice(Vector2D start, Vector2D end)
         {
@@ -21,7 +22,6 @@ namespace bbiwarg.Detectors.FingerDetection
             End = end;
             Mid = (start + end) / 2;
             LineSegment = new LineSegment2D(Start, End);
-            Length = Start.getDistanceTo(End); ;
         }
 
     }

+ 59 - 12
bbiwarg/Detectors/FingerDetection/FingerSliceTrail.cs

@@ -1,36 +1,83 @@
 using System;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using bbiwarg.Utility;
+using Emgu.CV;
 
 namespace bbiwarg.Detectors.FingerDetection
 {
     class FingerSliceTrail
     {
-        public List<FingerSlice> Slices { get; private set; }
-        public FingerSlice Start { get { return Slices[0]; } }
-        public FingerSlice End { get { return Slices[Slices.Count - 1]; } }
-        public int NumSlices { get { return Slices.Count; } }
-        public LineSegment2D LineSegment { get { return new LineSegment2D(End.Mid, Start.Mid); } }
+        private List<FingerSlice> slices;
+        private List<Point> pointsA;
+        private List<Point> pointsB;
+        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 FingerSliceTrail(FingerSlice slice)
         {
-            Slices = new List<FingerSlice>();
-            Slices.Add(slice);
+            slices = new List<FingerSlice>();
+            pointsA = new List<Point>();
+            pointsB = new List<Point>();
+            addSlice(slice);
         }
 
         public void addSlice(FingerSlice slice)
         {
-            Slices.Add(slice);
+            slices.Add(slice);
+            pointsA.Add(slice.Start - Constants.FingerContourMargin * slice.Direction);
+            pointsB.Add(slice.End + Constants.FingerContourMargin * slice.Direction);
+            pointsA.Add(slice.Start);
+            LineSegment = new LineSegment2D(StartSlice.Mid, slice.Mid);
         }
 
-        public Vector2D getEndDirection() {
-            int numSlicesToInnerEnd = Constants.FingerNumSlicesForRelativeDirection;
-            int innerEndIndex = Math.Max(0, NumSlices - numSlicesToInnerEnd);
+        public Vector2D getStartDirection()
+        {
+            int innerStartIndex = Math.Min(NumSlices, Constants.FingerNumSlicesForRelativeDirection);
+            return (EndSlice.Mid - slices[innerStartIndex].Mid).normalize();
+        }
+
+        public Vector2D getEndDirection()
+        {
+            int innerEndIndex = Math.Max(0, NumSlices - Constants.FingerNumSlicesForRelativeDirection);
+            return (EndSlice.Mid - slices[innerEndIndex].Mid).normalize();
+        }
+
+        public void removeFirstSlices(int numSlices) {
+            slices.RemoveRange(0, numSlices);
+            LineSegment = new LineSegment2D(StartSlice.Mid, EndSlice.Mid);
+        }
+
+        public void reverse() {
+            slices.Reverse();
+            pointsA.Reverse();
+            pointsB.Reverse();
+            LineSegment = new LineSegment2D(StartSlice.Mid, EndSlice.Mid);
+        }
+
+
+
+        public Contour<Point> getContour()
+        {
+            pointsA.Reverse();
+            List<Point> points = new List<Point>();
+            points.AddRange(pointsA);
+            points.AddRange(pointsB);
+            pointsA.Reverse();
 
-            return (End.Mid - Slices[innerEndIndex].Mid).normalize();
+            Contour<Point> contour = new Contour<Point>(new MemStorage());
+            foreach (Point p in points)
+            {
+                contour.Push(p);
+            }
+            return contour;
         }
     }
 }

+ 3 - 3
bbiwarg/Detectors/HandDetection/HandDetector.cs

@@ -45,11 +45,11 @@ namespace bbiwarg.Detectors.HandDetection
             foreach (Finger finger in fingers)
             {
                 // TODO: connect contour with other edges
-                Contour<Point> contour = finger.getContour();
+                Contour<Point> contour = finger.Contour;
                 image.FillConvexPoly(contour.ToArray(), new Gray(0));
-                image.DrawPolyline(finger.getContour().ToArray(), true, new Gray(255), 1);
+                image.DrawPolyline(finger.Contour.ToArray(), true, new Gray(255), 1);
 
-                FingerSlice slice = finger.SliceTrail.End;
+                FingerSlice slice = finger.SliceTrail.EndSlice;
                 Vector2D direction = slice.LineSegment.Line.Direction;
                 Vector2D start = slice.Start+(Constants.FingerContourMargin+Constants.FingerSliceOverlapFactor)*direction;
                 Vector2D end = slice.End-(Constants.FingerContourMargin+Constants.FingerSliceOverlapFactor)*direction;

+ 4 - 8
bbiwarg/Utility/LineSegment2D.cs

@@ -11,22 +11,18 @@ namespace bbiwarg.Utility
     {
         public Vector2D P1 { get; private set; }
         public Vector2D P2 { get; private set; }
+        public Vector2D Direction { get { return Line.Direction; } }
         public Line2D Line { get; private set; }
-        public float Length { get { return P1.getDistanceTo(P2); } }
+        public float Length { get; private set; }
 
         public LineSegment2D(Vector2D p1, Vector2D p2)
-        {
-            setPoints(p1, p2);
-        }
-
-        private void setPoints(Vector2D p1, Vector2D p2)
         {
             //endpoints
             P1 = p1;
             P2 = p2;
 
-            //line
-            Line = new Line2D(P1, P2-P1);
+            Line = new Line2D(P1, P2 - P1);
+            Length = P1.getDistanceTo(P2);
         }
 
         public float getParallelDistanceTo(LineSegment2D line)

+ 1 - 0
bbiwarg/Utility/Vector2D.cs

@@ -9,6 +9,7 @@ namespace bbiwarg.Utility
 {
     class Vector2D
     {
+        public static Vector2D Zero { get { return new Vector2D(0, 0); } }
         public float X { get; private set; }
         public float Y { get; private set; }
         public int IntX { get { return (int)X; } }