using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using Emgu.CV; using Emgu.CV.Structure; using bbiwarg.Graphics; using bbiwarg.Detectors.FingerDetection; using bbiwarg.Utility; namespace bbiwarg.Images { class DepthImage { private OutputImage outputImage; public Image Image { get; private set; } public Image 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 image, OutputImage outputImage) { this.outputImage = outputImage; Width = image.Width; Height = image.Height; image = image.SmoothMedian(Constants.DepthImageMedianSize); //threshold min&maxDepth MinDepth = findMinDepth(image); MaxDepth = (Int16)(MinDepth + Constants.DepthImageDepthRange); //smooth+threshold (dst = (src > (MaxDepth - MinDepth)) ? MaxDepth - MinDepth : src) Image = (image- MinDepth).ThresholdTrunc(new Gray(MaxDepth - MinDepth)).Convert(); Image = Image.SmoothMedian(Constants.DepthImageMedianSize); } public Int16 getDepthAt(Point point) { return getDepthAt(point.X, point.Y); } public Int16 getDepthAt(int x, int y) { return (Int16)(MinDepth + Image.Data[y, x, 0]); } public void setDepthAt(Point point, Int16 depth) { setDepthAt(point.X, point.Y, depth); } public void setDepthAt(int x, int y, Int16 depth) { Image.Data[y, x, 0] = (byte)(depth - MinDepth); } private Int16 findMinDepth(Image image) { // min and max values double[] min, max; // min and max locations Point[] minLoc, maxLoc; image.MinMax(out min, out max, out minLoc, out maxLoc); return (Int16)min[0]; } public void removeBackground(List fingers) { BackgroundMask = Image.Copy(); MCvConnectedComp comp = new MCvConnectedComp(); foreach (Finger finger in fingers) { Vector2D mid = finger.SliceTrail.Slices[finger.SliceTrail.NumSlices / 2].Mid; outputImage.fillCircle(mid.IntX, mid.IntY, 3, Color.Blue); if (BackgroundMask.Data[mid.IntY, mid.IntX,0] != 0) CvInvoke.cvFloodFill(BackgroundMask, mid, new MCvScalar(0), new MCvScalar(3), new MCvScalar(3), out comp, Emgu.CV.CvEnum.CONNECTIVITY.FOUR_CONNECTED, Emgu.CV.CvEnum.FLOODFILL_FLAG.DEFAULT, IntPtr.Zero); } BackgroundMask = BackgroundMask.Erode(3).Dilate(3).ThresholdBinary(new Gray(0), new Gray(255)); Image = Image.Or(BackgroundMask); } } }