Browse Source

-removed background noise
-fixed bug in finger direction detection

Alexander Hendrich 10 years ago
parent
commit
105e0b5d77

+ 4 - 3
bbiwarg/Constants.cs

@@ -13,7 +13,7 @@ namespace bbiwarg
         public static readonly bool TimerOutputAll = true;
 
         // depth image
-        public static readonly int DepthImageMedianSize = 5;
+        public static readonly int DepthImageMedianSize = 3;
         public static readonly int DepthImageDepthRange = 200; // <255
 
         // edge image
@@ -32,7 +32,7 @@ namespace bbiwarg
         public static readonly int FingerMinSize = 5;
         public static readonly int FingerNumSlicesForRelativeDirection = FingerRemoveNumSlicesForCorrection;
         public static readonly int FingerNumFramesUntilTracked = 2;
-        public static readonly int FingerOutSliceFactor = 5;
+        public static readonly int FingerOutSliceFactor = 10;
         public static readonly int FingerContourMargin = 2;
         public static readonly int FingerSliceOverlapFactor = 2;
         public static readonly float FingerMinSimilarityForTracking = 0.75f;
@@ -73,7 +73,8 @@ namespace bbiwarg
         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 FingerTipOutSliceColor = Color.Gray;
+        public static readonly Color FingerHandOutSliceColor = Color.DarkSlateGray;
 
         public static readonly Color TouchEventDetectedColor = ColorDetected;
         public static readonly Color TouchEventTrackedColor = ColorTracked;

+ 12 - 5
bbiwarg/Detectors/FingerDetection/FingerDetector.cs

@@ -275,8 +275,6 @@ namespace bbiwarg.Detectors.FingerDetection
 
             FingerSlice slice = new FingerSlice(p1, p2);
 
-            outputImage.drawLineSegment(slice.LineSegment, Constants.FingerOutSliceColor);
-
             return slice;
         }
 
@@ -296,14 +294,23 @@ namespace bbiwarg.Detectors.FingerDetection
             float startOutLength = float.MaxValue;
             float endOutLength = float.MaxValue;
 
-            if (!startOutSlice.Start.isOnBound(0, 0, maxX, maxY) && startOutSlice.End.isOnBound(0, 0, maxX, maxY))
+            if (startOutSlice.Start.isWithin(0, 0, maxX, maxY) && startOutSlice.End.isWithin(0, 0, maxX, maxY))
                 startOutLength = startOutSlice.Length;
 
-            if (!endOutSlice.Start.isOnBound(0, 0, maxX, maxY) && endOutSlice.End.isOnBound(0, 0, maxX, maxY))
+            if (endOutSlice.Start.isWithin(0, 0, maxX, maxY) && endOutSlice.End.isWithin(0, 0, maxX, maxY))
                 endOutLength = endOutSlice.Length;
 
-            if (startOutLength < endOutLength)
+            if (startOutLength <= endOutLength)
+            {
                 trail.Slices.Reverse();
+                outputImage.drawLineSegment(startOutSlice.LineSegment, Constants.FingerHandOutSliceColor);
+                outputImage.drawLineSegment(endOutSlice.LineSegment, Constants.FingerTipOutSliceColor);
+            }
+            else
+            {
+                outputImage.drawLineSegment(startOutSlice.LineSegment, Constants.FingerTipOutSliceColor);
+                outputImage.drawLineSegment(endOutSlice.LineSegment, Constants.FingerHandOutSliceColor);
+            }
 
             return trail;
         }

+ 1 - 1
bbiwarg/Detectors/HandDetection/Hand.cs

@@ -21,7 +21,7 @@ namespace bbiwarg.Detectors.HandDetection
         }
 
         public bool isInside(Vector2D point) {
-            return (Mask.Data[point.IntY, point.IntX, 0] == 1);
+            return (Mask.Data[point.IntY, point.IntX, 0] != 0);
         }
 
         public void addFinger(Finger finger) {

+ 17 - 9
bbiwarg/Detectors/HandDetection/HandDetector.cs

@@ -43,12 +43,18 @@ namespace bbiwarg.Detectors.HandDetection
             foreach (Finger finger in fingers)
             {
                 // TODO: connect contour with other edges
-                //Contour<Point> contour = finger.getContour();
-                //image.FillConvexPoly(contour.ToArray(), new Gray(0));
-                //image.DrawPolyline(finger.getContour().ToArray(), false, new Gray(255), 1);
+                Contour<Point> contour = finger.getContour();
+                image.FillConvexPoly(contour.ToArray(), new Gray(0));
+                image.DrawPolyline(finger.getContour().ToArray(), true, 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);
+                FingerSlice slice = finger.SliceTrail.End;
+                Vector2D direction = slice.LineSegment.Line.Direction;
+                Vector2D start = slice.Start+(Constants.FingerContourMargin+Constants.FingerSliceOverlapFactor)*direction;
+                Vector2D end = slice.End-(Constants.FingerContourMargin+Constants.FingerSliceOverlapFactor)*direction;
+                image.Draw(new Emgu.CV.Structure.LineSegment2D(start, end), new Gray(0), 2);
+                
+                //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>();
@@ -62,6 +68,7 @@ namespace bbiwarg.Detectors.HandDetection
                     {
                         hand.addFinger(finger);
                         newHand = false;
+                        break;
                     }
                 }
 
@@ -72,7 +79,7 @@ namespace bbiwarg.Detectors.HandDetection
                     CvInvoke.cvFloodFill(image, finger.HandPoint, new MCvScalar(255), new MCvScalar(1), new MCvScalar(1), out comp, Emgu.CV.CvEnum.CONNECTIVITY.FOUR_CONNECTED, Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, mask);
                     if (comp.area < maxArea * Constants.HandMaxSize)
                     {
-                        Hand hand = new Hand(mask.Copy(new Rectangle(1, 1, width, height)));
+                        Hand hand = new Hand(mask.Copy(new Rectangle(1, 1, width, height)).Mul(255));
                         hand.addFinger(finger);
                         Hands.Add(hand);
                     }
@@ -80,11 +87,12 @@ namespace bbiwarg.Detectors.HandDetection
             }
         }
 
-        private void drawHands() {
+        private void drawHands()
+        {
             int maxIndex = Math.Min(3, Hands.Count);
-            for (int i = 0; i < maxIndex ; i++)
+            for (int i = 0; i < maxIndex; i++)
             {
-                outputImage.Image[i] = Hands[i].Mask.Mul(255);
+                outputImage.Image[i] = Hands[i].Mask;
             }
         }
     }

+ 7 - 13
bbiwarg/Images/DepthImage.cs

@@ -8,6 +8,7 @@ using Emgu.CV;
 using Emgu.CV.Structure;
 using bbiwarg.Graphics;
 using bbiwarg.Detectors.FingerDetection;
+using bbiwarg.Detectors.HandDetection;
 using bbiwarg.Utility;
 
 namespace bbiwarg.Images
@@ -73,21 +74,14 @@ namespace bbiwarg.Images
             return (Int16)min[0];
         }
 
-        public void removeBackground(List<Finger> fingers) {
-            BackgroundMask = Image.Copy();
-            MCvConnectedComp comp = new MCvConnectedComp();
-
-            foreach (Finger finger in fingers) {
-                Vector2D mid = finger.SliceTrail.Slices[finger.SliceTrail.NumSlices / 2].Mid;
-
-                outputImage.fillCircle(mid.IntX, mid.IntY, 3, Color.Blue);
-
-                if (BackgroundMask.Data[mid.IntY, mid.IntX,0] != 0)
-                    CvInvoke.cvFloodFill(BackgroundMask, mid, new MCvScalar(0), new MCvScalar(3), new MCvScalar(3), out comp, Emgu.CV.CvEnum.CONNECTIVITY.FOUR_CONNECTED, Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, IntPtr.Zero);
+        public void removeBackground(List<Hand> hands) {
+            Image<Gray, byte> mask = Image.CopyBlank();
+            foreach (Hand hand in hands) {
+                mask = mask.Or(hand.Mask);
             }
 
-            BackgroundMask = BackgroundMask.Erode(3).Dilate(3).ThresholdBinary(new Gray(0), new Gray(255));
-            Image = Image.Or(BackgroundMask);
+
+            Image = Image.Or(255-mask);
         }
     }
 }

+ 2 - 2
bbiwarg/VideoHandle.cs

@@ -172,8 +172,8 @@ namespace bbiwarg
 
             //remove background noise
             Timer.start("removeBackground");
-            //depthImage.removeBackground(fingerDetector.Fingers);
-            //edgeImage = new EdgeImage(depthImage);
+            depthImage.removeBackground(handDetector.Hands);
+            edgeImage = new EdgeImage(depthImage);
             OutputImages[3].Image[0] = OutputImages[3].Image[1] = OutputImages[3].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
             Timer.stop("removeBackground");