Browse Source

Changed contour detection to use depth image (instead of edge image).
Added display of convexity defects.

Daniel Kauth 11 years ago
parent
commit
598f9190ea
3 changed files with 31 additions and 14 deletions
  1. 3 0
      bbiwarg/Graphics/OutputWindow.cs
  2. 27 13
      bbiwarg/Images/PalmImage.cs
  3. 1 1
      bbiwarg/VideoHandle.cs

+ 3 - 0
bbiwarg/Graphics/OutputWindow.cs

@@ -121,7 +121,10 @@ namespace bbiwarg.Graphics
 
 
                     // show palm contour
                     // show palm contour
                     if (videoHandle.isPalmPointAt(x, y))
                     if (videoHandle.isPalmPointAt(x, y))
+                    {
                         red = Int16.MaxValue;
                         red = Int16.MaxValue;
+                        green = blue = 0;
+                    }
 
 
                     depthTextureData[index] = red;
                     depthTextureData[index] = red;
                     depthTextureData[index + 1] = green;
                     depthTextureData[index + 1] = green;

+ 27 - 13
bbiwarg/Images/PalmImage.cs

@@ -16,19 +16,20 @@ namespace bbiwarg.Images
     class PalmImage
     class PalmImage
     {
     {
         private Image<Gray, Byte> image;
         private Image<Gray, Byte> image;
+        private Image<Gray, Byte> fingerSliceMask;
         private Image<Gray, Byte> output;
         private Image<Gray, Byte> output;
         private int width, height;
         private int width, height;
         
         
-        public PalmImage(EdgeImage edgeImage, FingerDetector fingerDetector)
+        public PalmImage(DepthImage depthImage, FingerDetector fingerDetector)
         {
         {
-            image = edgeImage.getImage().Clone();
+            image = depthImage.getImage().Convert<Byte>(delegate(short s) { return (s == depthImage.getMaxDepth()) ? (byte) 0 : (byte) 1; });
             width = image.Width;
             width = image.Width;
             height = image.Height;
             height = image.Height;
 
 
-            List<Finger> trackedFingers = fingerDetector.Fingers;
+            List<Finger> detectedFingers = fingerDetector.Fingers;
             Finger leftMost = null;
             Finger leftMost = null;
             float minX = float.MaxValue;
             float minX = float.MaxValue;
-            foreach (Finger f in trackedFingers)
+            foreach (Finger f in detectedFingers)
             {
             {
                 float midX = ((f.Hand + f.Tip) / 2).X;
                 float midX = ((f.Hand + f.Tip) / 2).X;
                 if (midX < minX)
                 if (midX < minX)
@@ -38,8 +39,8 @@ namespace bbiwarg.Images
                 }
                 }
             }
             }
 
 
-            Image<Gray, Byte> fingerSliceMask = new Image<Gray, byte>(width, height, new Gray(1));
-            foreach (Finger f in trackedFingers)
+            fingerSliceMask = new Image<Gray, byte>(width, height, new Gray(1));
+            foreach (Finger f in detectedFingers)
             {
             {
                 if (f != leftMost)
                 if (f != leftMost)
                 {
                 {
@@ -50,27 +51,27 @@ namespace bbiwarg.Images
                         {
                         {
                             int y = (int)start.Y;
                             int y = (int)start.Y;
                             for (int x = (int)start.X; x <= (int)end.X; ++x)
                             for (int x = (int)start.X; x <= (int)end.X; ++x)
-                                image.Data[y, x, 0] = 0;
+                                fingerSliceMask.Data[y, x, 0] = 0;
                         }
                         }
                         else
                         else
                         {
                         {
                             int x = (int)start.X;
                             int x = (int)start.X;
                             for (int y = (int)start.Y; y <= (int)end.Y; ++y)
                             for (int y = (int)start.Y; y <= (int)end.Y; ++y)
-                                image.Data[y, x, 0] = 0;
+                                fingerSliceMask.Data[y, x, 0] = 0;
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
 
 
-            image = image.And(fingerSliceMask.Erode(3));
+            fingerSliceMask = fingerSliceMask.Erode(2);
+            image = image.And(fingerSliceMask);
 
 
             findContour();
             findContour();
         }
         }
 
 
         private void findContour()
         private void findContour()
         {
         {
-            image.Dilate(1);
-            Contour<Point> contour = image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST);
+            Contour<Point> contour = image.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
 
 
             Contour<Point> maxContour = contour;
             Contour<Point> maxContour = contour;
             double maxPerimeter = 0;
             double maxPerimeter = 0;
@@ -83,10 +84,23 @@ namespace bbiwarg.Images
                 }
                 }
                 contour = contour.HNext;
                 contour = contour.HNext;
             }
             }
+        
+            Contour<Point> contourPoly = maxContour; //.ApproxPoly(0);
+            Seq<Point> hull = contourPoly.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
+            Seq<MCvConvexityDefect> defects = contourPoly.GetConvexityDefacts(new MemStorage(), Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
 
 
             output = new Image<Gray, byte>(width, height, new Gray(0));
             output = new Image<Gray, byte>(width, height, new Gray(0));
-            output.Draw(maxContour, new Gray(1), 1);
-            output.Draw(maxContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE), new Gray(1), 1);
+            output.Draw(contourPoly, new Gray(1), 1);
+            output.Draw(hull, new Gray(1), 1);
+
+            foreach (MCvConvexityDefect defect in defects)
+            {
+                Point s = defect.StartPoint;
+                Point e = defect.EndPoint;
+                Point d = defect.DepthPoint;
+
+                output.Draw(new LineSegment2DF(d, new Point((s.X + e.X) / 2, (s.Y + e.Y) / 2)), new Gray(1), 1);
+            }
         }
         }
 
 
         public bool belongsToPalm(int x, int y)
         public bool belongsToPalm(int x, int y)

+ 1 - 1
bbiwarg/VideoHandle.cs

@@ -128,7 +128,7 @@ namespace bbiwarg
             touchDetector = new TouchDetector(fingerTracker.getFingers(), depthImage, touchImage);
             touchDetector = new TouchDetector(fingerTracker.getFingers(), depthImage, touchImage);
             touchTracker.setDetectedTouchEventsThisFrame(touchDetector.getTouchEvents(), touchImage);
             touchTracker.setDetectedTouchEventsThisFrame(touchDetector.getTouchEvents(), touchImage);
 
 
-            palmImage = new PalmImage(edgeImage, fingerDetector);
+            palmImage = new PalmImage(depthImage, fingerDetector);
         }
         }
     }
     }
 }
 }