Explorar el Código

Changed the way convexity defects caused by fingers are removed.

Daniel Kauth hace 10 años
padre
commit
fbc3f20e29

+ 3 - 0
bbiwarg/Constants.cs

@@ -34,6 +34,9 @@ namespace bbiwarg
         public static readonly Color PalmConvexHullColor = Color.Green;
         public static readonly Color PalmThumbDefectColor = Color.Lime;
 
+        // palm detection
+        public static readonly float PalmMinDefectMidFingerLineDistance = 20; // defects with mid point ((start + end) / 2) closer than this to a finger line are removed 
+    
         // 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)

+ 12 - 9
bbiwarg/Detectors/Palm/PalmDetector.cs

@@ -63,8 +63,8 @@ namespace bbiwarg.Detectors.Palm
             findLongestPalmContour();
             if (palmContour != null)
             {
-                findConvexityDefactsSortedByDepth();
-                removeConvexityDefectsNearFingerTips();
+                findConvexityDefectsSortedByDepth();
+                removeConvexityDefectsCausedByFingers();
 
                 findHandPoints();
 
@@ -208,7 +208,7 @@ namespace bbiwarg.Detectors.Palm
             }
         }
 
-        private void findConvexityDefactsSortedByDepth()
+        private void findConvexityDefectsSortedByDepth()
         {
             convexityDefects = new List<MCvConvexityDefect>(palmContour.GetConvexityDefacts(new MemStorage(), Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE));
             convexityDefects.Sort(delegate(MCvConvexityDefect d1, MCvConvexityDefect d2)
@@ -221,19 +221,22 @@ namespace bbiwarg.Detectors.Palm
             });
         }
 
-        private void removeConvexityDefectsNearFingerTips()
+        private void removeConvexityDefectsCausedByFingers()
         {
             List<MCvConvexityDefect> newDefects = new List<MCvConvexityDefect>();
             foreach (MCvConvexityDefect d in convexityDefects)
             {
-                float minFingerTipDist = float.MaxValue;
+                float minFingerLineDist = float.MaxValue;
                 foreach (Finger f in fingers)
                 {
-                    float dist = f.Tip.getDistanceTo(new Vector2D(d.DepthPoint));
-                    if (dist < minFingerTipDist)
-                        minFingerTipDist = dist;
+                    Vector2D mid = (new Vector2D(d.StartPoint) + new Vector2D(d.EndPoint)) / 2.0f;
+                    
+                    float dist = f.LineSegment.getDistanceTo(mid);
+                    if (dist < minFingerLineDist)
+                        minFingerLineDist = dist;
                 }
-                if (minFingerTipDist > 10)
+                
+                if (minFingerLineDist >= Constants.PalmMinDefectMidFingerLineDistance)
                     newDefects.Add(d);
             }
             convexityDefects = newDefects;

+ 1 - 1
bbiwarg/Graphics/OutputWindow.cs

@@ -165,7 +165,7 @@ namespace bbiwarg.Graphics
 
             Timer.stop("onRenderFrame");
             
-            Timer.outputAll();
+            //Timer.outputAll();
         }
 
     }

+ 18 - 0
bbiwarg/Utility/LineSegment2D.cs

@@ -55,6 +55,24 @@ namespace bbiwarg.Utility
             return Math.Min(Math.Min(distanceP1A1, distanceP1A2), Math.Min(distanceP2A1, distanceP2A2));
         }
 
+        public float getDistanceTo(Vector2D point)
+        {
+            // http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
+            float l2 = (P1 - P2).dotProduct(P1 - P2);  // i.e. |w-v|^2 -  avoid a sqrt
+            if (l2 == 0.0) 
+                return point.getDistanceTo(P1);   // v == w case
+            // Consider the line extending the segment, parameterized as v + t (w - v).
+            // We find projection of point p onto the line. 
+            // It falls where t = [(p-v) . (w-v)] / |w-v|^2
+            float t = (point - P1).dotProduct(P2 - P1) / l2;
+            if (t < 0.0) 
+                return point.getDistanceTo(P1);       // Beyond the 'v' end of the segment
+            else if (t > 1.0) 
+                return point.getDistanceTo(P2);  // Beyond the 'w' end of the segment
+            Vector2D projection = P1 + t * (P2 - P1);  // Projection falls on the segment
+            return point.getDistanceTo(projection);
+        }
+
         public override string ToString()
         {
             return (int)P1.X + "|" + (int)P1.Y + " --- " + (int)P2.X + "|" + (int)P2.Y;