Browse Source

Added another constraint for the palm quad and a method to automatically remove an invalid palm quad.

Daniel Kauth 10 years ago
parent
commit
a61ac74175

+ 4 - 2
bbiwarg/Constants.cs

@@ -12,8 +12,8 @@ namespace bbiwarg
     class Constants
     {
         // Logger
-        public static readonly LogSubject LogLevel =
-            LogSubject.None;
+        public static readonly LogSubject LogLevel = 0;
+            //LogSubject.Timer;
         
         // Output
         public static readonly int OutputNumImages = 5;
@@ -79,6 +79,8 @@ namespace bbiwarg
         public static readonly int PalmNumFramesNoHandReset = 5;
         public static readonly float PalmMinAreaQuotient = 0.6f;
         public static readonly float PalmMaxAreaQuotient = 1.4f;
+        public static readonly float PalmMinPrecentageQuadForeground = 0.8f;
+        public static readonly float PalmMaxPrecentageQuadForegroundReset = 0.5f;
 
         //palm Grid
         public static readonly int PalmGridRows = 3;

+ 26 - 9
bbiwarg/Recognition/PalmRecognition/PalmDetector.cs

@@ -28,7 +28,7 @@ namespace bbiwarg.Recognition.PalmRecognition
         private Vector2D thumbDefectDepth;
         private Kalman2DPositionFilter thumbDefectDepthFilter, thumbDefectStartFilter, thumbDefectEndFilter;
         private int numFramesNoHandFound;
-        private float lastPalmQuadArea;
+        private Quadrangle lastPalmQuad;
         private List<Hand> hands;
 
         public Quadrangle PalmQuad { get; private set; }
@@ -44,7 +44,7 @@ namespace bbiwarg.Recognition.PalmRecognition
                                                                 Constants.PalmThumbDefectmYY, Constants.PalmThumbDefectProcessNoise);
         }
 
-        public void findPalmQuad(OutputImage outputImage, List<Hand> hands)
+        public void findPalmQuad(OutputImage outputImage, List<Hand> hands, Image<Gray, Byte> foregroundMask)
         {
             this.outputImage = outputImage;
             this.hands = hands;
@@ -84,7 +84,7 @@ namespace bbiwarg.Recognition.PalmRecognition
                 findConvexityDefectsSortedByDepth();
                 if (pointingHand != null)
                     removeConvexityDefectsCausedByFingers();
-                findHandPoints();
+                findHandPoints(foregroundMask);
             }
 
             if (hands.Count == 0)
@@ -93,6 +93,10 @@ namespace bbiwarg.Recognition.PalmRecognition
                 if (numFramesNoHandFound == Constants.PalmNumFramesNoHandReset)
                     reset();
             }
+            else
+            {
+                numFramesNoHandFound = 0;
+            }
 
             draw();
         }
@@ -106,7 +110,7 @@ namespace bbiwarg.Recognition.PalmRecognition
             PalmQuad = null;
             PalmHandSide = Hand.HandSide.Left;
             numFramesNoHandFound = 0;
-            lastPalmQuadArea = 0.0f;
+            lastPalmQuad = null;
         }
 
         private void findLongestPalmContour()
@@ -199,7 +203,15 @@ namespace bbiwarg.Recognition.PalmRecognition
             return null;
         }
 
-        private void findHandPoints()
+        float getForegroundPixelPercentage(Quadrangle quad, Image<Gray, Byte> foregroundMask)
+        {
+            float numPixelsInMask = quad.Mask.CountNonzero()[0];
+            float numPixelsInMaskInForeground = (quad.Mask & foregroundMask).CountNonzero()[0];
+
+            return numPixelsInMaskInForeground / numPixelsInMask;
+        }
+
+        private void findHandPoints(Image<Gray, Byte> foregroundMask)
         {
             MCvConvexityDefect? thumbDefect = findThumbDefect();
 
@@ -262,15 +274,20 @@ namespace bbiwarg.Recognition.PalmRecognition
                 bottomRight = bottomLeft + handWidth;
                 topRight = bottomRight + 1.2f * handLength - 0.3f * handWidth;
 
-                Quadrangle quad = new Quadrangle(bottomLeft, topLeft, topRight, bottomRight);
-                if (lastPalmQuadArea == 0.0f ||
-                    (quad.Area / lastPalmQuadArea >= Constants.PalmMinAreaQuotient && quad.Area / lastPalmQuadArea <= Constants.PalmMaxAreaQuotient))
+                Quadrangle quad = new Quadrangle(bottomLeft, topLeft, topRight, bottomRight, foregroundMask.Width, foregroundMask.Height);
+
+                if ((lastPalmQuad == null ||
+                    (quad.Area / lastPalmQuad.Area >= Constants.PalmMinAreaQuotient && quad.Area / lastPalmQuad.Area <= Constants.PalmMaxAreaQuotient)) &&
+                    getForegroundPixelPercentage(quad, foregroundMask) >= Constants.PalmMinPrecentageQuadForeground)
                 {
                     PalmQuad = quad;
                     PalmHandSide = palmHand.Side;
-                    lastPalmQuadArea = PalmQuad.Area;
+                    lastPalmQuad = PalmQuad;
                 }
             }
+
+            if (lastPalmQuad != null && getForegroundPixelPercentage(lastPalmQuad, foregroundMask) <= Constants.PalmMaxPrecentageQuadForegroundReset)
+                reset();
         }
 
         private void draw()

+ 18 - 7
bbiwarg/Utility/Quadrangle.cs

@@ -9,6 +9,7 @@ using System.Drawing;
 using bbiwarg.Recognition.HandRecognition;
 
 using Emgu.CV;
+using Emgu.CV.Structure;
 
 namespace bbiwarg.Utility
 {
@@ -20,20 +21,30 @@ namespace bbiwarg.Utility
         public Vector2D TopRight { get; private set; }
         public Vector2D BottomRight { get; private set; }
         public float Area {get; private set;}
+        public Image<Gray, Byte> Mask { get; private set; }
 
-        public Quadrangle(Vector2D bottomLeft, Vector2D topLeft, Vector2D topRight, Vector2D bottomRight)
+        public Quadrangle(Vector2D bottomLeft, Vector2D topLeft, Vector2D topRight, Vector2D bottomRight, int width, int height)
         {
             BottomLeft = bottomLeft;
             TopLeft = topLeft;
             TopRight = topRight;
             BottomRight = bottomRight;
 
-            Contour<PointF> points = new Contour<PointF>(new MemStorage());
-            points.Push(BottomLeft);
-            points.Push(TopLeft);
-            points.Push(TopRight);
-            points.Push(BottomRight);
-            Area = (float) points.Area;
+            Contour<PointF> contourPoints = new Contour<PointF>(new MemStorage());
+            contourPoints.Push(BottomLeft);
+            contourPoints.Push(TopLeft);
+            contourPoints.Push(TopRight);
+            contourPoints.Push(BottomRight);
+            Area = (float) contourPoints.Area;
+
+            Mask = new Image<Gray, byte>(width, height);
+
+            Point[] polyPoints = new Point[4];
+            polyPoints[0] = BottomLeft;
+            polyPoints[1] = TopLeft;
+            polyPoints[2] = TopRight;
+            polyPoints[3] = BottomRight;
+            Mask.FillConvexPoly(polyPoints, new Gray(255));
         }
 
 

+ 1 - 1
bbiwarg/VideoHandle.cs

@@ -199,7 +199,7 @@ namespace bbiwarg
             Timer.start("palmDetection");
             if (newStarted)
                 palmDetector.reset();
-            palmDetector.findPalmQuad(OutputImages[3], handDetector.Hands);
+            palmDetector.findPalmQuad(OutputImages[3], handDetector.Hands, handDetector.HandMask);
             Timer.stop("palmDetection");
 
             //detect touchEvents