Sfoglia il codice sorgente

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

Daniel Kauth 11 anni fa
parent
commit
29d87aebb7

+ 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);
         }
     }
 }