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