浏览代码

Added contour and convex hull based on edge image with area around fingerslices (except for left most finger) removed.

Daniel Kauth 11 年之前
父节点
当前提交
29d87aebb7
共有 3 个文件被更改,包括 45 次插入37 次删除
  1. 4 1
      bbiwarg/Detectors/Fingers/FingerSliceTrail.cs
  2. 39 34
      bbiwarg/Images/PalmImage.cs
  3. 2 2
      bbiwarg/VideoHandle.cs

+ 4 - 1
bbiwarg/Detectors/Fingers/FingerSliceTrail.cs

@@ -27,6 +27,9 @@ namespace bbiwarg.Detectors.Fingers
             slices.Add(slice);
         }
 
-
+        public List<FingerSlice> getSlices()
+        {
+            return slices;
+        }
     }
 }

+ 39 - 34
bbiwarg/Images/PalmImage.cs

@@ -16,53 +16,61 @@ namespace bbiwarg.Images
     class PalmImage
     {
         private Image<Gray, Byte> image;
+        private Image<Gray, Byte> output;
         private int width, height;
-        bool[,] inContour;
         
-        public PalmImage(EdgeImage edgeImage, FingerTracker fingerTracker)
+        public PalmImage(EdgeImage edgeImage, FingerDetector fingerDetector)
         {
-            image = edgeImage.getImage(); //.Clone();
+            image = edgeImage.getImage().Clone();
             width = image.Width;
             height = image.Height;
-            
-            foreach (Finger f in fingerTracker.getFingers())
-            {
-                Vector<float> tip = new Vector<float>(new float[] { f.Tip.X, f.Tip.Y });
-                Vector<float> hand = new Vector<float>(new float[] { f.Hand.X, f.Hand.Y });
 
+            List<Finger> trackedFingers = fingerDetector.Fingers;
+            Finger leftMost = null;
+            float minX = float.MaxValue;
+            foreach (Finger f in trackedFingers)
+            {
+                float midX = ((f.Hand + f.Tip) / 2).X;
+                if (midX < minX)
+                {
+                    minX = midX;
+                    leftMost = f;
+                }
+            }
 
-                for (int x = 0; x < width; ++x)
+            Image<Gray, Byte> fingerSliceMask = new Image<Gray, byte>(width, height, new Gray(1));
+            foreach (Finger f in trackedFingers)
+            {
+                if (f != leftMost)
                 {
-                    for (int y = 0; y < height; ++y)
+                    foreach (FingerSlice s in f.SliceTrail.getSlices())
                     {
-                        if (image.Data[y, x, 0] != 0)
+                        Vector2D start = s.Start, end = s.End;
+                        if ((int)start.Y == (int)end.Y)
                         {
-                           Vector<float> p = new Vector<float>(new float[] { x, y });
-
-                            float l2 = (tip - hand) * (tip - hand);
-                            float t = (p - tip) * (hand - tip) / l2;
-                            if (t >= 0.0 && t <= 1.0)
-                            {
-                                Vector<float> tmp = hand - tip;
-                                tmp.multiply(t);
-                                Vector<float> projection = tip + tmp;
-
-                                if (p.distance(projection) <= 15)
-                                    image.Data[y, x, 0] = 0;
-                            }
+                            int y = (int)start.Y;
+                            for (int x = (int)start.X; x <= (int)end.X; ++x)
+                                image.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;
                         }
                     }
                 }
             }
 
+            image = image.And(fingerSliceMask.Erode(3));
+
             findContour();
         }
 
         private void findContour()
         {
-            //image = 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);
+            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> maxContour = contour;
             double maxPerimeter = 0;
@@ -76,17 +84,14 @@ namespace bbiwarg.Images
                 contour = contour.HNext;
             }
 
-            inContour = new bool[width, height];
-            if (maxContour != null)
-            {
-                foreach (Point p in maxContour)
-                    inContour[p.X, p.Y] = true;
-            }
+            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);
         }
 
         public bool belongsToPalm(int x, int y)
         {
-            return inContour[x, y];
+            return output.Data[y, x, 0] == 1;
         }
     }
 }

+ 2 - 2
bbiwarg/VideoHandle.cs

@@ -92,7 +92,7 @@ namespace bbiwarg
         }
 
         public bool isPalmPointAt(int x, int y) {
-            return false;// palmImage.belongsToPalm(x, y);
+            return palmImage.belongsToPalm(x, y);
         }
 
         public TouchImageState getTouchImageStateAt(int x, int y) {
@@ -128,7 +128,7 @@ namespace bbiwarg
             touchDetector = new TouchDetector(fingerTracker.getFingers(), depthImage, touchImage);
             touchTracker.setDetectedTouchEventsThisFrame(touchDetector.getTouchEvents(), touchImage);
 
-            //palmImage = new PalmImage(edgeImage, fingerTracker);
+            palmImage = new PalmImage(edgeImage, fingerDetector);
         }
     }
 }