Example #1
0
        /**
         * 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;
        }
Example #2
0
        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;
        }
Example #3
0
        /**
         * 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;
        }