Parcourir la source

reworked output

Alexander Hendrich il y a 10 ans
Parent
commit
72371ec75a
4 fichiers modifiés avec 55 ajouts et 28 suppressions
  1. 1 1
      bbiwarg/Constants.cs
  2. 22 6
      bbiwarg/Images/DepthImage.cs
  3. 2 7
      bbiwarg/Images/EdgeImage.cs
  4. 30 14
      bbiwarg/VideoHandle.cs

+ 1 - 1
bbiwarg/Constants.cs

@@ -38,7 +38,7 @@ namespace bbiwarg
         public static readonly float PalmMinDefectMidFingerLineDistance = 20; // defects with mid point ((start + end) / 2) closer than this to a finger line are removed 
     
         // output window
-        public static readonly int NumImagesPerRow = 3;
+        public static readonly int NumImagesPerRow = 2;
         public static readonly float WindwoSizeFactor = 1f; // output window size is scaled by this factor (from necessary size for images)
     }
 }

+ 22 - 6
bbiwarg/Images/DepthImage.cs

@@ -7,32 +7,33 @@ using System.Threading.Tasks;
 using Emgu.CV;
 using Emgu.CV.Structure;
 using bbiwarg.Graphics;
+using bbiwarg.Detectors.Fingers;
+using bbiwarg.Utility;
 
 namespace bbiwarg.Images
 {
     class DepthImage
     {
         public Image<Gray, byte> Image { get; private set; }
+        public Image<Gray, byte> BackgroundMask { get; private set; }
         public int Width { get; private set; }
         public int Height { get; private set; }
         public Int16 MinDepth { get; private set; }
         public Int16 MaxDepth { get; private set; }
 
-        public DepthImage(Image<Gray, Int16> image, OutputImage outputImage)
+        public DepthImage(Image<Gray, Int16> image)
         {
             Width = image.Width;
             Height = image.Height;
 
+            image = image.SmoothMedian(3);
+
             //threshold min&maxDepth
             MinDepth = findMinDepth(image);
             MaxDepth = (Int16)(MinDepth + 200); // max = minDepth+255 (else it can't fit whole range in byte image)
 
             //smooth+threshold (dst = (src > (MaxDepth - MinDepth)) ? MaxDepth - MinDepth : src)
-            Image = image.SmoothMedian(3).Sub(new Gray(MinDepth)).ThresholdTrunc(new Gray(MaxDepth - MinDepth)).Convert<Gray, byte>();
-
-            // draw depth
-            Image<Gray, byte> tmpDepth = (MaxDepth - MinDepth) - Image;
-            outputImage.Image[0] = outputImage.Image[1] = outputImage.Image[2] = tmpDepth;
+            Image = image.Sub(new Gray(MinDepth)).ThresholdTrunc(new Gray(MaxDepth - MinDepth)).Convert<Gray, byte>();
         }
 
         public Int16 getDepthAt(Point point)
@@ -77,5 +78,20 @@ 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.Tip + finger.Hand) / 2;
+                if(BackgroundMask.Data[mid.IntY, mid.IntX,0] != 0)
+                    CvInvoke.cvFloodFill(BackgroundMask, mid, new MCvScalar(0), new MCvScalar(5), new MCvScalar(5), out comp, Emgu.CV.CvEnum.CONNECTIVITY.FOUR_CONNECTED, Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, IntPtr.Zero);
+            }
+
+            BackgroundMask = BackgroundMask.ThresholdBinary(new Gray(0), new Gray(255));
+            Image = Image.Or(BackgroundMask);
+
+        }
     }
 }

+ 2 - 7
bbiwarg/Images/EdgeImage.cs

@@ -18,14 +18,9 @@ namespace bbiwarg.Images
     {
         public Image<Gray, Byte> Image { get; private set; }
 
-        public EdgeImage(DepthImage depthImage, OutputImage outputImage)
+        public EdgeImage(DepthImage depthImage)
         {
-            Image<Gray, byte> dimg = depthImage.Image * (255.0f / (float)(depthImage.MaxDepth - depthImage.MinDepth));
-            
-            Image = dimg.Canny(100, 75, 3);
-
-            // draw blue edges in outputImage
-            outputImage.Image[2] = Image.ThresholdBinary(new Gray(0), new Gray(1)).Mul(255);
+            Image = (depthImage.Image * (255.0f / (float)(depthImage.MaxDepth - depthImage.MinDepth))).Canny(100, 75, 3);
         }
 
         public EdgeImage(Image<Gray, Byte> edgeImage)

+ 30 - 14
bbiwarg/VideoHandle.cs

@@ -49,8 +49,6 @@ namespace bbiwarg
         private FingerTracker fingerTracker;
         private TouchTracker touchTracker;
 
-        private OutputImage edgeFingerOutputImage;
-        private OutputImage depthPalmTouchOutputImage;
         private TouchEventVisualizer touchEventVisualizer;
 
         private int videoFrame = 0;
@@ -130,48 +128,62 @@ namespace bbiwarg
 
             //create output images
             Timer.start("createOtherImages");
-            edgeFingerOutputImage = new OutputImage(Width, Height);
-            depthPalmTouchOutputImage = new OutputImage(Width, Height);
+            int numImages = 4;
+            OutputImages = new OutputImage[numImages];
+            for (int i = 0; i < numImages; i++) {
+                OutputImages[i] = new OutputImage(Width, Height);
+                    
+            }
             Timer.stop("createOtherImages");
 
             //create depthImage
             Timer.start("createDepthImage");
             Image<Gray, Int16> image = new Image<Gray, Int16>(Width, Height, Width * 2, inputFrame.RawDepthData);
-            depthImage = new DepthImage(image, depthPalmTouchOutputImage);
+            depthImage = new DepthImage(image);
+            Image<Gray, byte> tmpDepth = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
+            OutputImages[0].Image[0] = OutputImages[0].Image[1] = OutputImages[0].Image[2] = tmpDepth;
             Timer.stop("createDepthImage");
 
             // create edge image
             Timer.start("createEdgeImage");
-            edgeImage = new EdgeImage(depthImage, edgeFingerOutputImage);
+            edgeImage = new EdgeImage(depthImage);
+            OutputImages[1].Image[2] = edgeImage.Image.ThresholdBinary(new Gray(0), new Gray(1)).Mul(255);
             Timer.stop("createEdgeImage");
 
             //detect fingers
             Timer.start("fingerDetection");
-            fingerDetector = new FingerDetector(depthImage, edgeImage, edgeFingerOutputImage);
+            fingerDetector = new FingerDetector(depthImage, edgeImage, OutputImages[1]);
             Timer.stop("fingerDetection");
 
             //track fingers
             Timer.start("fingerTracking");
-            fingerTracker.setDetectedTouchEventsThisFrame(fingerDetector.Fingers, edgeFingerOutputImage);
+            fingerTracker.setDetectedTouchEventsThisFrame(fingerDetector.Fingers, OutputImages[1]);
             Timer.stop("fingerTracking");
 
+            //remove background noise
+            Timer.start("removeBackground");
+            depthImage.removeBackground(fingerTracker.TrackedFingers);
+            edgeImage = new EdgeImage(depthImage);
+            OutputImages[2].Image[0] = OutputImages[2].Image[1] = OutputImages[2].Image[2] = (depthImage.MaxDepth - depthImage.MinDepth) - depthImage.Image;
+            Timer.stop("removeBackground");
+
             //detect palm
             Timer.start("palmDetection");
-            palmDetector = new PalmDetector(depthImage, edgeImage, fingerDetector.Fingers, depthPalmTouchOutputImage);
+            palmDetector = new PalmDetector(depthImage, edgeImage, fingerDetector.Fingers, OutputImages[2]);
             if (sourceIsMovie() && CurrentFrame == 0)
                 PalmDetector.resetFilter();
             Timer.stop("palmDetection");
 
             //detect touchEvents
             Timer.start("touchDetection");
-            touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, depthPalmTouchOutputImage);
+            touchDetector = new TouchDetector(fingerTracker.TrackedFingers, depthImage, OutputImages[2]);
             if (palmDetector.PalmQuad != null)
                 palmTouchDetector = new PalmTouchDetector(touchDetector.TouchEvents, palmDetector.PalmQuad);
             Timer.stop("touchDetection");
 
             //track touchEvents
             Timer.start("touchTracking");
-            touchTracker.setDetectedTouchEventsThisFrame(touchDetector.TouchEvents, depthPalmTouchOutputImage);
+            touchTracker.setDetectedTouchEventsThisFrame(touchDetector.TouchEvents, OutputImages[2]);
             Timer.stop("touchTracking");
 
             // touch event visualizer
@@ -184,12 +196,16 @@ namespace bbiwarg
                 foreach (PalmTouchEvent e in palmTouchDetector.PalmTouchEvents)
                     touchEventVisualizer.addPalmTouchEvent(e, CurrentFrame);
                 touchEventVisualizer.updateImage();
+                OutputImages[3] = touchEventVisualizer.OutputImage;
             }
 
             // add borders
-            edgeFingerOutputImage.drawRectangle(0, 0, Width - 1, Height - 1, Color.White);
-            depthPalmTouchOutputImage.drawRectangle(0, 0, Width - 1, Height - 1, Color.White);
-            OutputImages = new OutputImage[] { edgeFingerOutputImage, depthPalmTouchOutputImage, touchEventVisualizer.OutputImage};
+            for (int i = 0; i < numImages; i++)
+            {
+                OutputImages[i].drawRectangle(0, 0, Width - 1, Height - 1, Color.White);
+
+            }
+
             Timer.stop("processFrameUpdate");
         }
     }