Browse Source

Added thumb defect to output.
Added Kalman Filters for thumb start and end point.

Daniel Kauth 11 years ago
parent
commit
99e164bfbb
3 changed files with 62 additions and 25 deletions
  1. 1 0
      bbiwarg/Constants.cs
  2. 59 23
      bbiwarg/Detectors/Palm/PalmDetector.cs
  3. 2 2
      bbiwarg/VideoHandle.cs

+ 1 - 0
bbiwarg/Constants.cs

@@ -32,6 +32,7 @@ namespace bbiwarg
         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;
 
         // output window
         public static readonly int NumImagesPerRow = 3;

+ 59 - 23
bbiwarg/Detectors/Palm/PalmDetector.cs

@@ -29,8 +29,11 @@ namespace bbiwarg.Detectors.Palm
 
         private Contour<Point> palmContour;
         private List<MCvConvexityDefect> convexityDefects;
-
-        private static Kalman2DPositionFilter thumbDefactFilter;
+        private Vector2D thumbDefectStart;
+        private Vector2D thumbDefectEnd;
+        private Vector2D thumbDefectDepth;
+        
+        private static Kalman2DPositionFilter thumbDefectDepthFilter, thumbDefectStartFilter, thumbDefectEndFilter;
 
         private bool valid = false;
         private Vector2D topLeft;
@@ -74,7 +77,9 @@ namespace bbiwarg.Detectors.Palm
 
         public static void resetFilter()
         {
-            thumbDefactFilter = null;
+            thumbDefectDepthFilter = null;
+            thumbDefectStartFilter = null;
+            thumbDefectEndFilter = null;
         }
 
         private List<Finger> getFingersWithoutThumb(List<Finger> detectedFingers)
@@ -137,25 +142,53 @@ namespace bbiwarg.Detectors.Palm
             return new Point(HelperFunctions.thresholdRange<int>(0, width - 1, pos.IntX), HelperFunctions.thresholdRange<int>(0, height - 1, pos.IntY));
         }
 
+        //public OutputImage i1, i2, i3, i4, i5, i6, i7, i8, i9;
         private void buildPointingHandMask()
         {
+            /*i1 = new OutputImage(width, height);
+            i2 = new OutputImage(width, height);
+            i3 = new OutputImage(width, height);
+            i4 = new OutputImage(width, height);
+            i5 = new OutputImage(width, height);
+            i6 = new OutputImage(width, height);
+            i7 = new OutputImage(width, height);
+            i8 = new OutputImage(width, height);
+            i9 = new OutputImage(width, height);*/
+
             pointingHandMask = new Image<Gray, byte>(width, height, new Gray(0));
 
-            fillFingerSlices(pointingHandMask, 1);
-            pointingHandMask = pointingHandMask.Dilate(1);
             // dst = (src > 0) ? 1 : 0;
             pointingHandMask = pointingHandMask.Or(edgeImage.Image.ThresholdBinary(new Gray(0), new Gray(1)));
-            pointingHandMask = pointingHandMask.Dilate(1);
-            
+            //i1.Image[0] = i1.Image[1] = i1.Image[2] = 255 * pointingHandMask;
+
+            pointingHandMask = pointingHandMask.Dilate(4);
+            //i2.Image[0] = i2.Image[1] = i2.Image[2] = 255 * pointingHandMask;
+           
+            fillFingerSlices(pointingHandMask, 1);
+            //i3.Image[0] = i3.Image[1] = i3.Image[2] = 255 * pointingHandMask;
+
+            //pointingHandMask = pointingHandMask.Dilate(1);
+            //i4.Image[0] = i4.Image[1] = i4.Image[2] = 255 * pointingHandMask;
+
             MCvConnectedComp tmp = new MCvConnectedComp();
             // fill with value 2
             CvInvoke.cvFloodFill(pointingHandMask.Ptr, getPointInPointingHand(), new MCvScalar(2), new MCvScalar(0), new MCvScalar(0), out tmp, 0, IntPtr.Zero);
 
             // dst = (src > 1) ? 0 : 1    (src > 1 <-> src == 2 <-> src filled by flood fill)
             pointingHandMask = pointingHandMask.ThresholdBinaryInv(new Gray(1), new Gray(1));
-            pointingHandMask = pointingHandMask.Erode(1);
+            //i5.Image[0] = i5.Image[1] = i5.Image[2] = 255 * pointingHandMask;
+            
+            pointingHandMask = pointingHandMask.Erode(8);
+            //i6.Image[0] = i6.Image[1] = i6.Image[2] = 255 * pointingHandMask;
+
             fillFingerSlices(pointingHandMask, 0);
+            //i7.Image[0] = i7.Image[1] = i7.Image[2] = 255 * pointingHandMask;
+            
             pointingHandMask = pointingHandMask.Erode(2);
+            //i8.Image[0] = i8.Image[1] = i8.Image[2] = 255 * pointingHandMask;
+            
+            // only debug
+            //i9.Image[0] = i9.Image[1] = i9.Image[2] = 255 * handImage.And(pointingHandMask);
         }
 
         private void findLongestPalmContour()
@@ -200,7 +233,7 @@ namespace bbiwarg.Detectors.Palm
                     if (dist < minFingerTipDist)
                         minFingerTipDist = dist;
                 }
-                if (minFingerTipDist > 20)
+                if (minFingerTipDist > 10)
                     newDefects.Add(d);
             }
             convexityDefects = newDefects;
@@ -212,38 +245,40 @@ namespace bbiwarg.Detectors.Palm
             {
                 MCvConvexityDefect thumbDefect = convexityDefects[0];
 
-                Vector2D thumb;
-                if (thumbDefactFilter == null)
+                thumbDefectDepth = new Vector2D(thumbDefect.DepthPoint);
+                thumbDefectStart = new Vector2D(thumbDefect.StartPoint);
+                thumbDefectEnd = new Vector2D(thumbDefect.EndPoint);
+                if (thumbDefectDepthFilter == null)
                 {
-                    thumb = new Vector2D(thumbDefect.DepthPoint);
-                    thumbDefactFilter = new Kalman2DPositionFilter(thumb, 1.0e-2f, 1.0e-2f);
+                    thumbDefectDepthFilter = new Kalman2DPositionFilter(thumbDefectDepth, 1.0e-2f, 1.0e-2f);
+                    thumbDefectStartFilter = new Kalman2DPositionFilter(thumbDefectStart, 1.0e-2f, 1.0e-2f);
+                    thumbDefectEndFilter = new Kalman2DPositionFilter(thumbDefectEnd, 1.0e-2f, 1.0e-2f);
                 }
                 else
                 {
-                    thumb = thumbDefactFilter.getCorrectedPosition(new Vector2D(thumbDefect.DepthPoint));
+                    thumbDefectDepth = thumbDefectDepthFilter.getCorrectedPosition(thumbDefectDepth);
+                    thumbDefectStart = thumbDefectStartFilter.getCorrectedPosition(thumbDefectStart);
+                    thumbDefectEnd = thumbDefectEndFilter.getCorrectedPosition(thumbDefectEnd);
                 }
 
-                Vector2D thumbDefectStart = new Vector2D(thumbDefect.StartPoint);
-                Vector2D thumbDefectEnd = new Vector2D(thumbDefect.EndPoint);
-
                 Vector2D handLength, handWidth;
-                if (thumb.getDistanceTo(thumbDefectStart) > thumb.getDistanceTo(thumbDefectEnd))
+                if (thumbDefectDepth.getDistanceTo(thumbDefectStart) > thumbDefectDepth.getDistanceTo(thumbDefectEnd))
                 {
                     //right hand
-                    handLength = thumbDefectStart - thumb;
+                    handLength = thumbDefectStart - thumbDefectDepth;
                     handWidth = 0.8f * new Vector2D(-handLength.Y, handLength.X);
                     topLeft = thumbDefectStart;
-                    bottomLeft = thumb - 0.4f * handLength;
+                    bottomLeft = thumbDefectDepth - 0.4f * handLength;
                     bottomRight = bottomLeft + handWidth;
                     topRight = bottomRight + 1.2f * handLength - 0.3f * handWidth;
                 }
                 else
                 {
                     //left hand
-                    handLength = thumbDefectEnd - thumb;
+                    handLength = thumbDefectEnd - thumbDefectDepth;
                     handWidth = 0.8f * new Vector2D(handLength.Y, -handLength.X);
                     topRight = thumbDefectEnd;
-                    bottomRight = thumb - 0.4f * handLength;
+                    bottomRight = thumbDefectDepth - 0.4f * handLength;
                     bottomLeft = bottomRight + handWidth;
                     topLeft = bottomLeft + 1.2f * handLength - 0.3f * handWidth;
                 }
@@ -266,6 +301,8 @@ namespace bbiwarg.Detectors.Palm
 
             if (PalmQuad != null)
             {
+                outputImage.drawLineSegment(new Utility.LineSegment2D(thumbDefectDepth, (thumbDefectStart + thumbDefectEnd) / 2.0f), Constants.PalmThumbDefectColor, 1);
+                
                 Vector2D[] vertices = PalmQuad.Vertices;
                 for (int i = 0; i < 4; ++i)
                     outputImage.drawLineSegment(new bbiwarg.Utility.LineSegment2D(vertices[i], vertices[(i + 1) % 4]), Constants.PalmQuadColor);
@@ -274,7 +311,6 @@ namespace bbiwarg.Detectors.Palm
             }
         }
 
-        
         private void drawGrid(Vector2D a, Vector2D b, Vector2D c, Vector2D d)
         {
             int numRows = 4;

+ 2 - 2
bbiwarg/VideoHandle.cs

@@ -188,8 +188,8 @@ namespace bbiwarg
             edgeFingerOutputImage.drawRectangle(0, 0, Width - 1, Height - 1, 255, 255, 255);
             depthPalmTouchOutputImage.drawRectangle(0, 0, Width - 1, Height - 1, 255, 255, 255);
             touchEventVisualizer.OutputImage.drawRectangle(0, 0, Width - 1, Height - 1, 255, 255, 255);
-            OutputImages = new OutputImage[] { edgeFingerOutputImage, depthPalmTouchOutputImage, touchEventVisualizer.OutputImage};
-
+            OutputImages = new OutputImage[] { edgeFingerOutputImage, depthPalmTouchOutputImage}; /*, palmDetector.i1, palmDetector.i2, palmDetector.i3, palmDetector.i4, palmDetector.i5, palmDetector.i6,
+                                               palmDetector.i7, palmDetector.i8, palmDetector.i9};*/
             Timer.stop("processFrameUpdate");
         }
     }