/// <summary>
        /// Adds a shape to a colored image using the original color image.
        /// </summary>
        /// <param name="Shape">The pretzel / shape to add</param>
        /// <param name="FinalImg">Add to this picture</param>
        /// <param name="Image">Original colored picture</param>
        /// <returns>Colored image with shapes</returns>
        public static Color[,] AddShapeToColorImage( Shape Shape, Color[ , ] FinalImg, Color[ , ] Image )
        {
            int XOffset = Shape.Origin.X;
            int YOffset = Shape.Origin.Y;

            for ( int y = 0; y < Shape.Grid.GetLength( 1 ); y++ )
                for ( int x = 0; x < Shape.Grid.GetLength( 0 ); x++ )
                    if ( Shape.Grid[ x, y ] )
                        FinalImg[ x + XOffset, y + YOffset ] = Image[ x + XOffset, y + YOffset ];

            return FinalImg;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sets the current and neighboring white pixels to the current label color. Applies 
        /// recursively onto the pixels to the left, right, up and down (using a stack)
        /// </summary>
        /// <param name="input"> The input picture </param>
        /// <param name="x"> Pixel's x coordinate </param>
        /// <param name="y"> Pixel's y coordinate </param>
        /// <param name="Shapes"> The target list of shapes </param>
        private static void LabelPixel( byte[ , ] input, int x, int y, List<Shape> Shapes )
        {
            if ( input[ x, y ] != 255 )
                return;

            Color = NextColor( Color );

            // Bounding values of the shape
            int maxX = 0, minX = int.MaxValue;
            int maxY = 0, minY = int.MaxValue;

            ConcurrentStack<Point> NeighbouringPixels = new ConcurrentStack<Point>( );
            ConcurrentDictionary<Point, byte> NeighbouringPixelsUsed = new ConcurrentDictionary<Point, byte>( );

            Point StartPoint = new Point( x, y );
            NeighbouringPixels.Push( StartPoint );
            NeighbouringPixelsUsed.AddOrUpdate( StartPoint, key => 0, ( key, value ) => value );

            // Lock for when editing shared members
            object Lock = new object( );

            while ( NeighbouringPixels.Count != 0 )
            {
                // Parallel for faster calculations
                Parallel.For( 0, NeighbouringPixels.Count, index =>
                {
                    Point CurrentPoint;
                    if ( !NeighbouringPixels.TryPop( out CurrentPoint ) )
                        return;

                    NeighbouringPixelsUsed.AddOrUpdate( CurrentPoint, key => 0, ( key, value ) => value );

                    lock ( Lock )
                    {
                        // Values for the bounding rectangle
                        if ( CurrentPoint.Y < minY )
                            minY = CurrentPoint.Y;
                        if ( CurrentPoint.Y > maxY )
                            maxY = CurrentPoint.Y;
                        if ( CurrentPoint.X < minX )
                            minX = CurrentPoint.X;
                        if ( CurrentPoint.X > maxX )
                            maxX = CurrentPoint.X;

                        // Set the pixel to the label's value
                        input[ CurrentPoint.X, CurrentPoint.Y ] = Color;
                    }

                    // Makes sure you do not exceed boundaries.
                    int smallestX = CurrentPoint.X > 0 ? -1 : 0;
                    int smallestY = CurrentPoint.Y > 0 ? -1 : 0;
                    int biggestX = CurrentPoint.X < ( input.GetLength( 0 ) - 1 ) ? 1 : 0;
                    int biggestY = CurrentPoint.Y < ( input.GetLength( 1 ) - 1 ) ? 1 : 0;

                    // For every neighbor...
                    for ( int ver = smallestY; ver <= biggestY; ver++ )
                    {
                        for ( int hor = smallestX; hor <= biggestX; hor++ )
                        {
                            Point NextPixel = new Point( CurrentPoint.X + hor, CurrentPoint.Y + ver );

                            //Check if the next pixel is white and if it isn't already in the stack.
                            if ( input[ NextPixel.X, NextPixel.Y ] == 255 && !NeighbouringPixelsUsed.ContainsKey( NextPixel ) )
                                NeighbouringPixels.Push( new Point( NextPixel.X, NextPixel.Y ) );
                        }
                    }
                } );
            }

            Shape S = new Shape( input, new Rectangle( minX, minY, maxX - minX, maxY - minY ), Color );
            Shapes.Add( S );
        }