فهرست منبع

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

Daniel Kauth 11 سال پیش
والد
کامیت
598f9190ea
3فایلهای تغییر یافته به همراه31 افزوده شده و 14 حذف شده
  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
                     if (videoHandle.isPalmPointAt(x, y))
+                    {
                         red = Int16.MaxValue;
+                        green = blue = 0;
+                    }
 
                     depthTextureData[index] = red;
                     depthTextureData[index + 1] = green;

+ 27 - 13
bbiwarg/Images/PalmImage.cs

@@ -16,19 +16,20 @@ namespace bbiwarg.Images
     class PalmImage
     {
         private Image<Gray, Byte> image;
+        private Image<Gray, Byte> fingerSliceMask;
         private Image<Gray, Byte> output;
         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;
             height = image.Height;
 
-            List<Finger> trackedFingers = fingerDetector.Fingers;
+            List<Finger> detectedFingers = fingerDetector.Fingers;
             Finger leftMost = null;
             float minX = float.MaxValue;
-            foreach (Finger f in trackedFingers)
+            foreach (Finger f in detectedFingers)
             {
                 float midX = ((f.Hand + f.Tip) / 2).X;
                 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)
                 {
@@ -50,27 +51,27 @@ namespace bbiwarg.Images
                         {
                             int y = (int)start.Y;
                             for (int x = (int)start.X; x <= (int)end.X; ++x)
-                                image.Data[y, x, 0] = 0;
+                                fingerSliceMask.Data[y, x, 0] = 0;
                         }
                         else
                         {
                             int x = (int)start.X;
                             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();
         }
 
         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;
             double maxPerimeter = 0;
@@ -83,10 +84,23 @@ namespace bbiwarg.Images
                 }
                 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.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)

+ 1 - 1
bbiwarg/VideoHandle.cs

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