AForge.Imaging.Filters.FlatFieldCorrection.ProcessFilter C# (CSharp) Method

ProcessFilter() protected method

Process the filter on the specified image.
protected ProcessFilter ( UnmanagedImage image ) : void
image UnmanagedImage Source image data.
return void
        protected override unsafe void ProcessFilter( UnmanagedImage image )
        {
            UnmanagedImage bgImage = null;
            BitmapData bgLockedData = null;

            // get image size
            int width  = image.Width;
            int height = image.Height;
            int offset = image.Stride - ( ( image.PixelFormat == PixelFormat.Format8bppIndexed ) ? width : width * 3 );
            
            // check if we have provided background
            if ( ( backgroundImage == null ) && ( unmanagedBackgroundImage == null ) )
            {
                // resize image to 1/3 of its original size to make bluring faster
                ResizeBicubic resizeFilter = new ResizeBicubic( (int) width / 3, (int) height / 3 );
                UnmanagedImage tempImage = resizeFilter.Apply( image );

                // create background image from the input image blurring it with Gaussian 5 times
                GaussianBlur blur = new GaussianBlur( 5, 21 );

                blur.ApplyInPlace( tempImage );
                blur.ApplyInPlace( tempImage );
                blur.ApplyInPlace( tempImage );
                blur.ApplyInPlace( tempImage );
                blur.ApplyInPlace( tempImage );

                // resize the blurred image back to original size
                resizeFilter.NewWidth  = width;
                resizeFilter.NewHeight = height;
                bgImage = resizeFilter.Apply( tempImage );

                tempImage.Dispose( );
            }
            else
            {
                if ( backgroundImage != null )
                {
                    // check background image
                    if ( ( width != backgroundImage.Width ) || ( height != backgroundImage.Height ) || ( image.PixelFormat != backgroundImage.PixelFormat ) )
                    {
                        throw new InvalidImagePropertiesException( "Source image and background images must have the same size and pixel format" );
                    }

                    // lock background image
                    bgLockedData = backgroundImage.LockBits(
                        new Rectangle( 0, 0, width, height ),
                        ImageLockMode.ReadOnly, backgroundImage.PixelFormat );

                    bgImage = new UnmanagedImage( bgLockedData );
                }
                else
                {
                    bgImage = unmanagedBackgroundImage;
                }
            }

            // get background image's statistics (mean value is used as correction factor)
            ImageStatistics bgStatistics = new ImageStatistics( bgImage );

            byte* src = (byte*) image.ImageData.ToPointer( );
            byte* bg  = (byte*) bgImage.ImageData.ToPointer( );

            // do the job
            if ( image.PixelFormat == PixelFormat.Format8bppIndexed )
            {
                // grayscale image
                double mean = bgStatistics.Gray.Mean;

                for ( int y = 0; y < height; y++ )
                {
                    for ( int x = 0; x < width; x++, src++, bg++ )
                    {
                        if ( *bg != 0 )
                        {
                            *src = (byte) Math.Min( mean * *src / *bg, 255 );
                        }
                    }
                    src += offset;
                    bg  += offset;
                }
            }
            else
            {
                // color image
                double meanR = bgStatistics.Red.Mean;
                double meanG = bgStatistics.Green.Mean;
                double meanB = bgStatistics.Blue.Mean;

                for ( int y = 0; y < height; y++ )
                {
                    for ( int x = 0; x < width; x++, src += 3, bg += 3 )
                    {
                        // red
                        if ( bg[RGB.R] != 0 )
                        {
                            src[RGB.R] = (byte) Math.Min( meanR * src[RGB.R] / bg[RGB.R], 255 );
                        }
                        // green
                        if ( bg[RGB.G] != 0 )
                        {
                            src[RGB.G] = (byte) Math.Min( meanG * src[RGB.G] / bg[RGB.G], 255 );
                        }
                        // blue
                        if ( bg[RGB.B] != 0 )
                        {
                            src[RGB.B] = (byte) Math.Min( meanB * src[RGB.B] / bg[RGB.B], 255 );
                        }
                    }
                    src += offset;
                    bg  += offset;
                }
            }

            if ( backgroundImage != null )
            {
                backgroundImage.UnlockBits( bgLockedData );
            }

            // dispose background image if it was not set manually
            if ( ( backgroundImage == null ) && ( unmanagedBackgroundImage == null ) )
            {
                bgImage.Dispose( );
            }
        }
    }