using BBIWARG.Utility; using Emgu.CV; using Emgu.CV.Structure; using System; using System.Drawing; namespace BBIWARG.Images { /// /// DepthImage stores a processed version of the depth image read by the camera as an /// public class DepthImage { /// /// the processed depth image /// public Image Image { get; private set; } /// /// the maximum depth which is considered important /// public UInt16 MaxDepth { get; private set; } /// /// the minimum depth in the raw depth image /// public UInt16 MinDepth { get; private set; } /// /// image size of the depth image /// public ImageSize Size { get; private set; } /// /// Construct a DepthImage from the raw depth data, the image size and a confidenceImage. /// Filters the image using confidenceImage and also applies thresholding and smoothing. /// /// the raw depth data /// the image size /// the confidence image public DepthImage(Image rawDepthImage) { Size = new ImageSize(rawDepthImage.Width, rawDepthImage.Height); // smooth with median filter rawDepthImage = rawDepthImage.SmoothMedian(Parameters.DepthImageMedianSize); // threshold min&maxDepth MinDepth = findMinDepth(rawDepthImage); MaxDepth = (UInt16)(MinDepth + Parameters.DepthImageDepthRange); // threshold (dst = (src > (MaxDepth - MinDepth)) ? MaxDepth - MinDepth : src) Image = (rawDepthImage - MinDepth).Convert().ThresholdTrunc(new Gray(MaxDepth - MinDepth)).Convert(); // smooth with median filter Image = Image.SmoothMedian(Parameters.DepthImageMedianSize); } /// /// Returns the depth in the processed image at a given point. /// /// the point /// depth at the point public UInt16 getDepthAt(Point point) { return getDepthAt(point.X, point.Y); } /// /// Returns the depth in the processed image at a given position. /// /// x coordinate of the position /// y coordinate of the position /// the depth at the position public UInt16 getDepthAt(int x, int y) { try { return (UInt16)(MinDepth + Image.Data[y, x, 0]); } catch (IndexOutOfRangeException e) { return (UInt16)(MinDepth + Image.Data[0, 0, 0]); } } /// /// Returns the depth in the processed image at a given position. /// It will move the x,y more to the center of the palm! /// /// x coordinate of the position /// y coordinate of the position /// the depth at the position public UInt16 getDepthAtFixed(int x0, int y0, int x1, int y1) { try { int rx = (int) ((x1 - x0) * 0.15f + x0); int ry = (int) ((y1 - y0) * 0.15f + y0); return (UInt16)(MinDepth + Image.Data[ry, rx, 0]); } catch (IndexOutOfRangeException e) { return (UInt16)(MinDepth + Image.Data[0, 0, 0]); } } /// /// Sets the depth in the processed image. /// /// point where the depth is set /// new depth value public void setDepthAt(Point point, UInt16 depth) { setDepthAt(point.X, point.Y, depth); } /// /// Sets the depth in the processed image. /// /// x coordinate of position to set depth /// y coordinate of position to set depth /// new depth value public void setDepthAt(int x, int y, UInt16 depth) { Image.Data[y, x, 0] = (byte)(depth - MinDepth); } /// /// Returns the minimum depth in an /// /// the image /// the minimum depth private UInt16 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 (UInt16)min[0]; } } }