public void subtract(Shape s) { int area = this.set.Count; Point? center = s.getCenter(); int cx = center.Value.X; int cy = center.Value.Y; foreach (Point? p in s.set) { this.set.Remove(p); } this.sumX -= area * cx; this.sumY -= area * cy; // BIG WARNING! Margin points and coords are not moved back. }
public ShapeAndBoolImage(Shape shape, bool[][] boolIm) { this.shape = shape; this.boolImage = boolIm; }
public void Add(Shape shape) { if (this.bottomMostPoint.Value.Y < shape.BottomMostPoint.Value.Y) { this.bottomMostPoint = shape.BottomMostPoint; } if (this.topMostPoint.Value.Y > shape.TopMostPoint.Value.Y) { this.topMostPoint = shape.TopMostPoint; } if (this.leftMostPoint.Value.X > shape.LeftMostPoint.Value.X) { this.leftMostPoint = shape.LeftMostPoint; } if (this.rightMostPoint.Value.X < shape.RightMostPoint.Value.X) { this.rightMostPoint = shape.RightMostPoint; } this.Set.UnionWith(shape.Set); }
public object Clone() { HashSet<Point?> clonedSet = new HashSet<Point?>(this.set); Shape clonedShape = new Shape(clonedSet, this.sumX, this.sumY, this.leftMostPoint, this.rightMostPoint, this.topMostPoint, this.bottomMostPoint); return clonedShape; }
public static bool[,] shape2BoolIm(Shape shape, int wi, int he) { bool[,] boolImage = new bool[he, wi]; foreach (Point? pt in shape.Set) { boolImage[pt.Value.Y, pt.Value.X] = true; } return boolImage; }
public static Shape reduceShapeToAreaAndRatio(Shape originalShape, Point? firstPoint, double ratioLimit, int areaLowerLimit, int areaHigherLimit) { int[] neighx = { -1, 0, 1, -1, 1, -1, 0, 1 }; int[] neighy = { -1, -1, 1, 0, 0, 1, 1, 1 }; if (ratioLimit <= 0) { return null; } double ratioLimitInv = 1 / ratioLimit; int px = 0, py = 0, nx, ny; Point? head, neighbour; Shape reducedShape = new Shape(); int reducedArea = 0; double reducedRatio = 1.0; Queue<Point?> queue = new Queue<Point?>(); if (originalShape == null) { return null; } if (!originalShape.contains(firstPoint)) { return null; } queue.Enqueue(firstPoint); while (true) { head = queue.Dequeue(); reducedShape.Add(head); reducedRatio = reducedShape.getAspectRatio(); reducedArea = reducedShape.Set.Count; py = head.Value.Y; for (int i = 0; i < 8; i++) { nx = px + neighx[i]; ny = py + neighy[i]; neighbour = new Point(nx, ny); if ((originalShape.contains(neighbour)) && (!reducedShape.contains(neighbour)) && (!queue.Contains(neighbour)) && (reducedArea + queue.Count < areaHigherLimit)) { queue.Enqueue(neighbour); } } /* * Stop condition. It's weird but it's faster */ if (!(queue.Count > 0)) { break; } else { if (reducedArea < areaLowerLimit) { continue; } else if (reducedArea > areaHigherLimit) { break; } else { if ((ratioLimitInv < reducedRatio) && (reducedRatio < ratioLimit)) { continue; } else { break; } } } } if ((reducedShape.Set.Count < areaLowerLimit) || ((ratioLimitInv < reducedRatio) && (reducedRatio < ratioLimit))) { return null; } return reducedShape; }
/** * Extracts a horizontal or vertical shape of the original Shape. * The area of the new, smaller flat shape will be smaller thatn the areaLimit. * sizeLimit specifies the width of the flat, extracted shape. */ public static Shape reduceShapeHVAreaLimit(Shape originalShape, Point? firstPoint, int sizeLimit, bool horizontal, int areaLimit) { int px, py, nx, ny; int[] neighx = { -1, 0, 1, -1, 1, -1, 0, 1 }, neighy = { -1, -1, 1, 0, 0, 1, 1, 1 }; Shape reducedShape = new Shape(); Queue<Point?> queue = new Queue<Point?>(); if (originalShape == null) { return null; } if (!originalShape.contains(firstPoint)) { return null; } queue.Enqueue(firstPoint); while (true) { Point? head = queue.Dequeue(); reducedShape.Add(head); int reducedArea = reducedShape.Area; Point? shapeCenter = reducedShape.getCenter(); px = head.Value.X; py = head.Value.Y; for (int i = 0; i < 8; i++) { nx = px + neighx[i]; ny = py + neighy[i]; Point? neighbour = new Point(nx, ny); if ((originalShape.contains(neighbour)) && (!reducedShape.contains(neighbour)) && (!queue.Contains(neighbour)) && (queue.Count() + reducedArea < areaLimit) && (((horizontal) && (Math.Abs(nx - shapeCenter.Value.X) < sizeLimit)) || ((!horizontal) && (Math.Abs(ny - shapeCenter.Value.Y) < sizeLimit))) ) { queue.Enqueue(neighbour); } } if ((reducedArea > areaLimit) || (queue.Count == 0)) { break; } } return reducedShape; }
public static Shape[] findThinShapes(Shape shape, int n, int outerTryLimit, int innerTryLimit, double thinnessLimit, int areaLowerLimit, int areaHigherLimit) { Random r = new Random(); Shape workingShape = (Shape)shape.Clone(); Shape[] thinShapes = new Shape[n]; int outerTries = 0; int maxFound = 0; int i = 0; while ((i < n) && (outerTries < outerTryLimit)) { Shape thinShape = null; int innerTries = 0; while ((thinShape == null) && (innerTries < innerTryLimit)) { // this may be real slow Point? randomPoint = workingShape.getPoint(r.Next(shape.Set.Count)); thinShape = ImageAlgorithms.reduceShapeToAreaAndRatio(workingShape, randomPoint, thinnessLimit, areaLowerLimit, areaHigherLimit); innerTries++; } if (thinShape == null) { outerTries++; i = 0; workingShape = (Shape)shape.Clone(); continue; } thinShapes[i] = thinShape; workingShape.subtract(thinShape); i++; if (i > maxFound) { maxFound = i; } } //System.out.format("most thinshapes found: %d\n", maxFound); if (outerTries == outerTryLimit) { //return null; return thinShapes; } return thinShapes; }
/** * Finds a contiguos shape in the boolean image by doing breadth first search. * It also deletes the found pixels from the source image, cutting the shape out from the original. */ public static Shape breadthShapeExtendAndCut(bool[,] source, Point? firstPoint) { int i; int height = source.GetLength(0), width = source.Length / source.GetLength(0); int px, py, nx, ny; Point? head, neighbour; Queue<Point?> queue; int[] neighx = { -1, 0, 1, -1, 1, -1, 0, 1 }, neighy = { -1, -1, 1, 0, 0, 1, 1, 1 }; Shape shape = new Shape(); queue = new Queue<Point?>(); queue.Enqueue(firstPoint); while (queue.Count > 0) { head = queue.Dequeue(); shape.Add(head); px = head.Value.X; py = head.Value.Y; source[py, px] = false; for (i = 0; i < 8; i++) { nx = px + neighx[i]; ny = py + neighy[i]; neighbour = new Point(nx, ny); if ((nx >= 0) && (nx < width) && (ny >= 0) && (ny < height) && (source[ny, nx]) && (!shape.contains(neighbour)) && (!queue.Contains(neighbour))) { queue.Enqueue(neighbour); source[ny, nx] = false; } } } return shape; }