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];
}
}
}