using BBIWARG.Utility;
using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Drawing;
namespace BBIWARG.Images
{
///
/// EdgeImage creates an edge image form a depth image and stores it as an
///
public class EdgeImage
{
///
/// the edge image
///
public Image Image { get; private set; }
///
/// dilated version of the edge image
///
public Image RoughImage { get; private set; }
///
/// the size of the edge image
///
public ImageSize Size { get; private set; }
///
/// Constructs a new EdgeImage from a depth image.
///
/// the depth image
public EdgeImage(DepthImage depthImage)
{
Size = depthImage.Size;
Image = depthImage.Image.ConvertScale(255f / (depthImage.MaxDepth - depthImage.MinDepth), 0);
Image = Image.Canny(Parameters.EdgeImageCannyStartThreshold, Parameters.EdgeImageCannyLinkingThreshold, Parameters.EdgeImageCannySize);
Image = Image.ThresholdBinary(new Gray(0), new Gray(1));
RoughImage = Image.Dilate(Parameters.EdgeImageRoughNumDilationIterations);
}
///
/// Creates a new EdgeImage from the data of another edge image.
///
/// the edge image
/// dilated version of the edge image
/// size of the edge image
public EdgeImage(Image edgeImage, Image roughEdgeImage, ImageSize size)
{
Size = size;
Image = edgeImage;
RoughImage = roughEdgeImage;
}
///
/// Returns a copy of this edge image.
///
/// copy of this edge image
public EdgeImage copy()
{
return new EdgeImage(Image.Copy(), RoughImage.Copy(), Size);
}
///
/// Returns the first vector starting at start and going in the given direction, which rounds to a point containing an edge in the rough edge image
/// or null if no such vector is found.
///
/// start position
/// search direction
/// maximum number of steps in direction
/// the positions of the next rough edge
public Vector2D findNextRoughEdge(Vector2D start, Vector2D direction, int maxSearchSize = 0)
{
Vector2D maxGrow = (Size.MaxPixel - start) / direction;
Vector2D maxDecline = start / direction.getAbsolute();
int maxStepsX;
if (direction.X > 0)
maxStepsX = maxGrow.IntX;
else if (direction.X < 0)
maxStepsX = maxDecline.IntX;
else
maxStepsX = int.MaxValue;
int maxStepsY;
if (direction.Y > 0)
maxStepsY = maxGrow.IntY;
else if (direction.Y < 0)
maxStepsY = maxDecline.IntY;
else
maxStepsY = int.MaxValue;
int maxSteps = Math.Min(maxStepsX, maxStepsY);
if (maxSearchSize != 0)
maxSteps = Math.Min(maxSteps, maxSearchSize);
Vector2D end = start.copy();
for (int i = 0; i < maxSteps; i++)
{
end += direction;
if (isRoughEdgeAt(end))
return end;
}
return null;
}
///
/// Returns true iff an edge is at a point.
///
/// the point
/// true iff an edge is at point
public bool isEdgeAt(Point point)
{
return isEdgeAt(point.X, point.Y);
}
///
/// Returns true iff an edge is at a position.
///
/// x coordinate of the position
/// y coordinate of the position
/// true iff an edge is at the position
public bool isEdgeAt(int x, int y)
{
return Image.Data[y, x, 0] > 0;
}
///
/// Returns true iff an edge is at a point in the rough edge image.
///
/// the point
/// true iff an edge is at point in the rough edge image
public bool isRoughEdgeAt(Point point)
{
return isRoughEdgeAt(point.X, point.Y);
}
///
/// Returns true iff an edge is at a position in the rough edge image.
///
/// x coordinate of the position
/// y coordinate of the position
/// true iff an edge is at the position in the rough edge image
public bool isRoughEdgeAt(int x, int y)
{
return RoughImage.Data[y, x, 0] > 0;
}
///
/// Removes all edges inside the given polygon in both edge images.
///
/// the polygon
public void removeEdgesInsidePolygon(Point[] polygon)
{
Image.FillConvexPoly(polygon, new Gray(0));
RoughImage.FillConvexPoly(polygon, new Gray(0));
}
}
}