Quellcode durchsuchen

-parameter tuning
-improvements to finger+hand detection

Alexander Hendrich vor 11 Jahren
Ursprung
Commit
57b7c9f81d

+ 39 - 31
bbiwarg/Constants.cs

@@ -9,32 +9,8 @@ namespace bbiwarg
 {
     class Constants
     {
-        // colors
-        public static readonly Color ColorDetected = Color.White;
-        public static readonly Color ColorTracked = Color.Yellow;
-
-        //public static readonly Color EdgeColor = Color.Blue; // edgeImage draw direct to blue chanel from outputImage
-
-        public static readonly Color FingerSliceColor = Color.Magenta;
-        public static readonly Color FingerDetectedColor = ColorDetected;
-        public static readonly Color FingerTrackedColor = ColorTracked;
-        public static readonly Color FingerOutSliceColor = Color.DarkSlateGray;
-
-        public static readonly Color TouchEventDetectedColor = ColorDetected;
-        public static readonly Color TouchEventTrackedColor = ColorTracked;
-        public static readonly Color TouchEventTipColor = Color.CornflowerBlue;
-        public static readonly Color TouchEventAreaMatchedSubtractColor = Color.DarkOrange;
-        public static readonly Color TouchEventAreaNonMatchedSubtractColor = Color.DarkSlateGray;
-        public static readonly Color TouchEventStatusBarColor = Color.Green;
-
-        public static readonly Color TouchEventVisualizerLineColor = Color.White;
-        public static readonly Color TouchEventVisualizerPointColor = Color.Red;
-
-        public static readonly Color PalmQuadColor = Color.Blue;
-        public static readonly Color PalmGridColor = Color.CornflowerBlue;
-        public static readonly Color PalmConturColor = Color.Red;
-        public static readonly Color PalmConvexHullColor = Color.Green;
-        public static readonly Color PalmThumbDefectColor = Color.Lime;
+        // BBIWARG
+        public static readonly bool TimerOutputAll = true;
 
         // depth image
         public static readonly int DepthImageMedianSize = 5;
@@ -48,16 +24,17 @@ namespace bbiwarg
 
         // finger detection
         public static readonly int FingerStepSize = 2;
-        public static readonly int FingerMinNumSlices = 10;
-        public static readonly int FingerRemoveNumSlicesForCorrection = 3;
+        public static readonly int FingerMinNumSlices = 30 / FingerStepSize;
+        public static readonly int FingerRemoveNumSlicesForCorrection = 5;
         public static readonly int FingerMaxGapCounter = 10;
         public static readonly int FingerMaxSliceDifferencePerStep = 5;
-        public static readonly int FingerMaxSize = 35;
+        public static readonly int FingerMaxSize = 30;
         public static readonly int FingerMinSize = 5;
-        public static readonly int FingerNumSlicesForRelativeDirection = 5;
+        public static readonly int FingerNumSlicesForRelativeDirection = FingerRemoveNumSlicesForCorrection;
         public static readonly int FingerNumFramesUntilTracked = 2;
         public static readonly int FingerOutSliceFactor = 5;
-        public static readonly int FingerContourMargin = 3;
+        public static readonly int FingerContourMargin = 2;
+        public static readonly int FingerSliceOverlapFactor = 2;
         public static readonly float FingerMinSimilarityForTracking = 0.75f;
 
         // hand detection
@@ -84,5 +61,36 @@ namespace bbiwarg
         // output window
         public static readonly int NumImagesPerRow = 3;
         public static readonly float WindwoSizeFactor = 1f; // output window size is scaled by this factor (from necessary size for images)
+
+
+
+
+
+        // colors
+        public static readonly Color ColorDetected = Color.White;
+        public static readonly Color ColorTracked = Color.Yellow;
+
+        //public static readonly Color EdgeColor = Color.Blue; // edgeImage draw direct to blue chanel from outputImage
+
+        public static readonly Color FingerSliceColor = Color.Magenta;
+        public static readonly Color FingerDetectedColor = ColorDetected;
+        public static readonly Color FingerTrackedColor = ColorTracked;
+        public static readonly Color FingerOutSliceColor = Color.DarkSlateGray;
+
+        public static readonly Color TouchEventDetectedColor = ColorDetected;
+        public static readonly Color TouchEventTrackedColor = ColorTracked;
+        public static readonly Color TouchEventTipColor = Color.CornflowerBlue;
+        public static readonly Color TouchEventAreaMatchedSubtractColor = Color.DarkOrange;
+        public static readonly Color TouchEventAreaNonMatchedSubtractColor = Color.DarkSlateGray;
+        public static readonly Color TouchEventStatusBarColor = Color.Green;
+
+        public static readonly Color TouchEventVisualizerLineColor = Color.White;
+        public static readonly Color TouchEventVisualizerPointColor = Color.Red;
+
+        public static readonly Color PalmQuadColor = Color.Blue;
+        public static readonly Color PalmGridColor = Color.CornflowerBlue;
+        public static readonly Color PalmConturColor = Color.Red;
+        public static readonly Color PalmConvexHullColor = Color.Green;
+        public static readonly Color PalmThumbDefectColor = Color.Lime;
     }
 }

+ 10 - 9
bbiwarg/Detectors/FingerDetection/FingerDetector.cs

@@ -38,7 +38,7 @@ namespace bbiwarg.Detectors.FingerDetection
 
             Fingers = new List<Finger>();
 
-            for (int y = 1; y < maxY; y += 5) //y++ for 100% coverage, but y+=5 for 99% coverage and 3 times better perfomance
+            for (int y = 1; y < maxY; y += 5)
             {
                 for (int x = 1; x < maxX; x++)
                 {
@@ -57,7 +57,9 @@ namespace bbiwarg.Detectors.FingerDetection
                             {
                                 FingerSliceTrail trail = findFingerSliceTrail(slice, edgeDirection);
                                 if (trail != null && trail.NumSlices > Constants.FingerMinNumSlices)
+                                {
                                     createFingerFromTrail(trail);
+                                }
                             }
                         }
                     }
@@ -95,7 +97,7 @@ namespace bbiwarg.Detectors.FingerDetection
                     trail.addSlice(nextSlice);
                     trail = expandTrail(trail);
 
-                    if (trail.NumSlices > Constants.FingerMinNumSlices)
+                    if (trail.NumSlices > Constants.FingerMinNumSlices / 2)
                     {
                         trail.Slices.RemoveRange(0, Constants.FingerRemoveNumSlicesForCorrection);
                         trail.Slices.Reverse();
@@ -126,7 +128,7 @@ namespace bbiwarg.Detectors.FingerDetection
 
             while (currentPosition.isWithin(0, 0, maxX, maxY) && gapCounter <= Math.Min(numSlices, Constants.FingerMaxGapCounter))
             {
-                if(reversed)
+                if (reversed)
                     nextSlice = findFingerSliceFromMid(currentPosition, currentDirection.getInverse());
                 else
                     nextSlice = findFingerSliceFromMid(currentPosition, currentDirection);
@@ -168,7 +170,7 @@ namespace bbiwarg.Detectors.FingerDetection
         }
         private FingerSlice findFingerSliceFromStartEdge(Vector2D start, Vector2D direction)
         {
-            Vector2D end = findNextEdge(start+3*direction, direction);
+            Vector2D end = findNextEdge(start + Constants.FingerSliceOverlapFactor * direction, direction);
             if (end == null) return null;
 
             return getFingerSlice(start, end);
@@ -223,8 +225,8 @@ namespace bbiwarg.Detectors.FingerDetection
             int maxY = depthImage.Height - 1;
 
             Vector2D direction = (end - start).normalize();
-            Vector2D beforeStart = (start - direction).moveInBound(0, 0, maxX, maxY);
-            Vector2D behindEnd = (end + direction).moveInBound(0, 0, maxY, maxY);
+            Vector2D beforeStart = (start - Constants.FingerSliceOverlapFactor * direction).moveInBound(0, 0, maxX, maxY);
+            Vector2D behindEnd = (end + Constants.FingerSliceOverlapFactor * direction).moveInBound(0, 0, maxY, maxY);
 
             FingerSlice slice = new FingerSlice(beforeStart, behindEnd);
             if (slice.Length >= Constants.FingerMinSize && slice.Length <= Constants.FingerMaxSize && fingerSliceDepthTest(slice))
@@ -267,7 +269,7 @@ namespace bbiwarg.Detectors.FingerDetection
             Vector2D dirOrth1 = direction.getOrthogonal(true);
             Vector2D dirOrth2 = direction.getOrthogonal(false);
 
-            Vector2D outPoint = (start + Constants.FingerOutSliceFactor * Constants.FingerStepSize * direction).moveInBound(0, 0, maxX, maxY);
+            Vector2D outPoint = (start + Constants.FingerOutSliceFactor * direction).moveInBound(0, 0, maxX, maxY);
             Vector2D p1 = findNextEdge(outPoint, dirOrth1, false, false, true);
             Vector2D p2 = findNextEdge(outPoint, dirOrth2, false, false, true);
 
@@ -288,7 +290,7 @@ namespace bbiwarg.Detectors.FingerDetection
 
             Vector2D direction = (end.Mid - start.Mid).normalize();
 
-            FingerSlice startOutSlice = findOutSlice(start.Mid, -1 * direction);
+            FingerSlice startOutSlice = findOutSlice(start.Mid, direction.getInverse());
             FingerSlice endOutSlice = findOutSlice(end.Mid, direction);
 
             float startOutLength = float.MaxValue;
@@ -313,7 +315,6 @@ namespace bbiwarg.Detectors.FingerDetection
             {
                 outputImage.drawLineSegment(trail.Slices[i].LineSegment, Constants.FingerSliceColor);
             }
-            //outputImage.drawPolygon(finger.getBoundingPolygon(), 0);
             outputImage.drawLineSegment(finger.LineSegment, Constants.FingerDetectedColor);
             outputImage.drawContour(finger.getContour(), Color.Red, 1);
         }

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

@@ -29,6 +29,7 @@ namespace bbiwarg.Detectors.HandDetection
             this.outputImage = outputImage;
 
             detectHands();
+            drawHands();
         }
 
         private void detectHands()
@@ -41,8 +42,8 @@ namespace bbiwarg.Detectors.HandDetection
             //draw top finger slice
             foreach (Finger finger in fingers)
             {
-                FingerSlice slice = finger.SliceTrail.Start;
-                image.Draw(new Emgu.CV.Structure.LineSegment2D(slice.Start, slice.End), new Gray(255), 1);
+                FingerSlice slice = finger.SliceTrail.Slices[1];
+                image.Draw(new Emgu.CV.Structure.LineSegment2D(slice.Start, slice.End), new Gray(255), 2);
             }
 
             Hands = new List<Hand>();
@@ -72,8 +73,11 @@ namespace bbiwarg.Detectors.HandDetection
                     }
                 }
             }
+        }
 
-            for (int i = 0; i < Math.Min(3, Hands.Count); i++)
+        private void drawHands() {
+            int maxIndex = Math.Min(3, Hands.Count);
+            for (int i = 0; i < maxIndex ; i++)
             {
                 outputImage.Image[i] = Hands[i].Mask.Mul(255);
             }

+ 2 - 1
bbiwarg/Graphics/OutputWindow.cs

@@ -165,7 +165,8 @@ namespace bbiwarg.Graphics
 
             Timer.stop("onRenderFrame");
             
-            Timer.outputAll();
+            if(Constants.TimerOutputAll)
+                Timer.outputAll();
         }
 
     }

+ 1 - 0
bbiwarg/Images/EdgeImage.cs

@@ -54,6 +54,7 @@ namespace bbiwarg.Images
         public void removeEdgesInsidePolygon(Point[] polygon)
         {
             Image.FillConvexPoly(polygon, new Gray(0));
+            RoughImage.FillConvexPoly(polygon, new Gray(0));
         }
 
         public EdgeImage copy()

+ 3 - 2
bbiwarg/VideoHandle.cs

@@ -10,6 +10,7 @@ using bbiwarg.Detectors.FingerDetection;
 using bbiwarg.Detectors.PalmDetection;
 using bbiwarg.Detectors.TouchDetection;
 using bbiwarg.Detectors.HandDetection;
+using bbiwarg.Detectors.HandDetection;
 using bbiwarg.Images;
 using bbiwarg.InputProviders;
 using Emgu.CV;
@@ -131,14 +132,14 @@ namespace bbiwarg
             Timer.stop("readInputData");
 
             //create output images
-            Timer.start("createOtherImages");
+            Timer.start("createOutputImages");
             int numImages = 5;
             OutputImages = new OutputImage[numImages];
             for (int i = 0; i < numImages; i++) {
                 OutputImages[i] = new OutputImage(Width, Height);
                     
             }
-            Timer.stop("createOtherImages");
+            Timer.stop("createOutputImages");
 
             //create depthImage
             Timer.start("createDepthImage");