public void FindPeaksTest()
        {
            Bitmap hand = Properties.Resources.rhand;

            GaussianBlur median = new GaussianBlur(1.1);
            median.ApplyInPlace(hand);

            // Extract contour
            BorderFollowing bf = new BorderFollowing(1);
            List<IntPoint> contour = bf.FindContour(hand);

            hand = hand.Clone(new Rectangle(0, 0, hand.Width, hand.Height), PixelFormat.Format24bppRgb);

            // Find peaks
            KCurvature kcurv = new KCurvature(30, new DoubleRange(0, 45));
            // kcurv.Suppression = 30;
            var peaks = kcurv.FindPeaks(contour);

            List<IntPoint> supports = new List<IntPoint>();
            for (int i = 0; i < peaks.Count; i++)
            {
                int j = contour.IndexOf(peaks[i]);
                supports.Add(contour[(j + kcurv.K) % contour.Count]);
                supports.Add(contour[Accord.Math.Tools.Mod(j - kcurv.K, contour.Count)]);
            }

            // show(hand, contour, peaks, supports);

            Assert.AreEqual(2, peaks.Count);
            Assert.AreEqual(46, peaks[0].X);
            Assert.AreEqual(0, peaks[0].Y);
            Assert.AreEqual(2, peaks[1].X);
            Assert.AreEqual(11, peaks[1].Y);
        }
Exemple #2
0
        static DiffCalculator()
        {
            threshold = new Threshold(THERSHOLD);
            fillHoles = new FillHoles();
            fillHoles.MaxHoleHeight = 125;
            fillHoles.MaxHoleWidth = 125;
            fillHoles.CoupledSizeFiltering = true;

            gaussianBlur = new GaussianBlur(3, 11);
        }
        public static Bitmap DoIt(Bitmap bmp)
        {
            GaussianBlur blur = new GaussianBlur(10, 50);
            Bitmap blurred = blur.Apply(bmp);

            Bitmap ret = new Bitmap(blurred.Width, blurred.Height, blurred.PixelFormat);

            for (int y = 0; y < blurred.Height; y++)
            {
                for (int x = 0; x < blurred.Width; x++)
                {
                    Color blurredColor = blurred.GetPixel(x, y);
                    Color orinalColor = bmp.GetPixel(x, y);

                    Color newColor = Color.FromArgb((blurredColor.R + orinalColor.R * 2) / 3,
                        (blurredColor.G + orinalColor.G * 2) / 3,
                        (blurredColor.B + orinalColor.B * 2) / 3);

                    ret.SetPixel(x, y, newColor);
                }
            }

            GammaCorrection gc = new GammaCorrection(.8);
            gc.ApplyInPlace(ret);

            Sharpen sharpen = new Sharpen();
            sharpen.ApplyInPlace(ret);

            Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
            Bitmap gray = filter.Apply(ret);

            CannyEdgeDetector canny = new CannyEdgeDetector();
            gray = canny.Apply(gray);

            for (int y = 0; y < gray.Height; y++)
            {
                for (int x=0;x < gray.Width; x++)
                {
                    if(gray.GetPixel(x,y).R > 0)
                    {
                        Color retColor = ret.GetPixel(x, y);
                        Color newColor = Color.FromArgb(
                            (int)(retColor.R * .7),
                            (int)(retColor.G * .7),
                            (int)(retColor.B * .7));

                        ret.SetPixel(x, y, newColor);
                    }
                }
            }

            return ret;
        }
        public double GetTemperature()
        {
            var temp = 0.0;

            var image = Image.FromFile(filename);

            var grayscale = new Grayscale(0.2125, 0.7154, 0.0721);
            image = grayscale.Apply(image);

            var invert = new Invert();
            image = invert.Apply(image);

            var stats = new ImageStatistics(image);
            var levelsLinear = new LevelsLinear
            {
                InGray = stats.Gray.GetRange(2.90)
            };

            image = levelsLinear.Apply(image);

            var contrast = new ContrastStretch();
            image = contrast.Apply(image);

            var erosion = new Erosion();
            image = erosion.Apply(image);

            var blur = new GaussianBlur(2, 3);
            image = blur.Apply(image);

            var threshold = new Threshold(79);
            image = threshold.Apply(image);

            image.Save(processedFileName, System.Drawing.Imaging.ImageFormat.Jpeg);
            image.Dispose();
            var text = Recognise();

            double.TryParse(text.Replace(',', '.'), out temp);

            return temp;
        }
 public static Bitmap GaussianBlur(Bitmap bmp, int value)
 {
     // create filter with kernel size equal to 11
     // and Gaussia sigma value equal to 4.0
     GaussianBlur filter = new GaussianBlur(value, 11);
     // apply the filter
     filter.ApplyInPlace(bmp);
     return bmp;
 }
Exemple #6
0
        /// <summary>
        /// Processes the specified SRC image.
        /// </summary>
        /// <param name="srcImage">The SRC image.</param>
        /// <remarks></remarks>
        public void Process(Bitmap srcImage)
        {
            if (srcImage == null || srcImage.Width < 10 || srcImage.Height < 10) 
                return;

            resize.NewWidth = srcImage.Width / Scale;
            resize.NewHeight = srcImage.Height / Scale;

            FilteredBoard = resize.Apply(srcImage);

            if (Enhance) 
                ImageFilters.FlattenLighting(FilteredBoard);

            ImageFilters.HSLFilter(FilteredBoard, targetHue, targetSat, targetBri, hueTol, satTol, briTol);

            median.ApplyInPlace(FilteredBoard);
            GaussianBlur blr = new GaussianBlur(2, 2);
            blr.ApplyInPlace(FilteredBoard);

            TileBlobs.Clear();

            try
            {
                BlobCounter.ProcessImage(FilteredBoard);

                Blob[] blobs = BlobCounter.GetObjectsInformation();
                TileBlobs.Clear();

                foreach (Blob b in blobs)
                {
                    if (b.Area < 10) continue;
                    TileBlobs.Add(b);
                }
            }
            catch { }
        }
        private void SmoothEdges()
        {
            var d = 5;
            //Apply your Gaussian blur method to the image

            //(for example, with AForge.NET, you might use the following code:)
            var filter = new GaussianBlur(15, 15);

            filter.ApplyInPlace(Painting, new Rectangle(0, height/2 - d, width, 2*d));

            filter.ApplyInPlace(Painting, new Rectangle(width/2 - d, 0, 2*d, height));

            //                filter.ApplyInPlace(Painting);
        }
Exemple #8
0
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="image">Source image data.</param>
        ///
        protected override unsafe void ProcessFilter(UnmanagedImage image)
        {
            UnmanagedImage bgImage      = null;
            BitmapData     bgLockedData = null;

            // get image size
            var width  = image.Width;
            var height = image.Height;
            var offset = image.Stride - ((image.PixelFormat == PixelFormat.Format8bppIndexed) ? width : width * 3);

            // check if we have provided background
            if ((this.backgroundImage == null) && (this.unmanagedBackgroundImage == null))
            {
                // resize image to 1/3 of its original size to make bluring faster
                var resizeFilter = new ResizeBicubic((int)width / 3, (int)height / 3);
                var tempImage    = resizeFilter.Apply(image);

                // create background image from the input image blurring it with Gaussian 5 times
                var 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 (this.backgroundImage != null)
                {
                    // check background image
                    if ((width != this.backgroundImage.Width) || (height != this.backgroundImage.Height) || (image.PixelFormat != this.backgroundImage.PixelFormat))
                    {
                        throw new InvalidImagePropertiesException("Source image and background images must have the same size and pixel format");
                    }

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

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

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

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

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

                for (var y = 0; y < height; y++)
                {
                    for (var 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
                var meanR = bgStatistics.Red.Mean;
                var meanG = bgStatistics.Green.Mean;
                var meanB = bgStatistics.Blue.Mean;

                for (var y = 0; y < height; y++)
                {
                    for (var 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 (this.backgroundImage != null)
            {
                this.backgroundImage.UnlockBits(bgLockedData);
            }

            // dispose background image if it was not set manually
            if ((this.backgroundImage == null) && (this.unmanagedBackgroundImage == null))
            {
                bgImage.Dispose( );
            }
        }
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        /// 
        /// <param name="image">Source image data.</param>
        ///
        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( );
            }
        }
Exemple #10
0
 public static Bitmap gaussianBlur(this Bitmap bitmap, int blur)
 {
     AForge.Imaging.Filters.GaussianBlur filter = new AForge.Imaging.Filters.GaussianBlur(Convert.ToDouble(blur), 9);
     return(filter.Apply(AForge.Imaging.Image.Clone(bitmap, PixelFormat.Format24bppRgb)));
 }
 /// <summary>
 /// Blur image with Gauss
 /// </summary>
 /// <param name="image"></param>
 /// <param name="sigma">Gaussia sigma</param>
 /// <param name="kernelSize">Gaussia kermel</param>
 /// <returns></returns>
 public static Image Gauss(this Image image, double sigma, int kernelSize)
 {
     GaussianBlur blur = new GaussianBlur(sigma, kernelSize);
     return blur.Apply(new Bitmap(image));
 }
Exemple #12
0
        public void RunWorker()
        {
            while (true)
            {
                bool ajSuccess = false;
                resetEvent.WaitOne();

                frameMutex.WaitOne(); //RNM

                // Process image
                this.workerStatus = WorkerStatus.Busy;

                if (processingImage.Width != grayBuffer.Width || processingImage.Height != grayBuffer.Height)
                    grayBuffer = new Bitmap(processingImage.Width, processingImage.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

                System.Drawing.Imaging.BitmapData imageBD = LockTotalBitmap(processingImage, System.Drawing.Imaging.ImageLockMode.ReadWrite);
                System.Drawing.Imaging.BitmapData grayBufferBD = LockTotalBitmap(grayBuffer, System.Drawing.Imaging.ImageLockMode.ReadWrite);

                try
                {
                    // create unmanaged images
                    UnmanagedImage imageUMI = new UnmanagedImage(imageBD);
                    UnmanagedImage grayBufferUMI = new UnmanagedImage(grayBufferBD);

                    // Apply grayscale and otsu filters
                    if (this.probabilityMap == null)
                    {
                        // Grayscale Otsu Thresholding
                        grayFilter.Apply(imageUMI, grayBufferUMI);

                        otsuFilter.ApplyInPlace(grayBufferUMI);
                        //Median mf = new Median(5);
                        //mf.ApplyInPlace(grayBufferUMI);

                    }
                    else
                    {
                        // BPM Colour Thresholding
                        probabilityMap.TresholdImage(imageUMI, grayBufferUMI);

                        //Median mf = new Median(5);
                        //mf.ApplyInPlace(grayBufferUMI);

                        GaussianBlur gb = new GaussianBlur(3.0);
                        Threshold t = new Threshold(127);
                        gb.ApplyInPlace(grayBufferUMI);
                        t.ApplyInPlace(grayBufferUMI);

                        //AForge.Imaging.Filters.Erosion er = new AForge.Imaging.Filters.Erosion();
                        //er.ApplyInPlace(grayBufferUMI);
                    }

                    bool ccSuccess = componentFinder.FindBlobs(grayBufferUMI);

                    // Create adjacency matrix
                    if (ccSuccess)
                    {
                        ajSuccess = regionAdjacencyGraph.ConstructGraph(componentFinder.ObjectLabels, componentFinder.ObjectCount, processingImage.Width, processingImage.Height);
                    }

                    // If producing the graph has failed, for example due to too many regions, stop processing the current frame.
                    if (!ajSuccess)
                    {
                        if (detectedMarkerList != null)
                            detectedMarkerList.Clear();
                        if (permittedMarkerList != null)
                            permittedMarkerList.Clear();
                        this.workerStatus = WorkerStatus.Finished;
                        continue;
                    }

                    detectedMarkerList = markerDetector.FindMarkers(componentFinder, regionAdjacencyGraph);
                    permittedMarkerList = markerDetector.PermitMarkers(detectedMarkerList, permittedCodes);
                }
                catch (Exception e)
                {
                    //RNM
                    resetEvent.Reset();
                    frameMutex.ReleaseMutex();
                    MessageBox.Show("An exception occurred during Marker Detection: " + e.Message);

                    throw;
                }
                finally
                {
                    processingImage.UnlockBits(imageBD);
                    grayBuffer.UnlockBits(grayBufferBD);

                    if (!ajSuccess)
                    {
                        resetEvent.Reset();
                        frameMutex.ReleaseMutex();
                    }

                }

                if (detectedMarkerList != null && permittedMarkerList.Count > 0)
                {

                    //send marker xml.
                    sendMarkerXml(permittedMarkerList);

                    // Draw other UI components
                    using (Graphics g = Graphics.FromImage(processingImage))
                    {
                        Pen boundingBoxPen = new Pen(Color.Blue, 4.0f);
                        boundingBoxPen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
                        boundingBoxPen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
                        Font markerFont = new Font("Arial", 16.0f);

                        for (int marker = 0; marker < permittedMarkerList.Count; marker++)
                        {
                            int markerID = permittedMarkerList[marker].ID;
                            string markerCode = permittedMarkerList[marker].Code;
                            BoundingBox bb = componentFinder.ObjectBoundingBoxes[markerID];

                            g.DrawLine(boundingBoxPen, new System.Drawing.Point(bb.x1, bb.y1), new System.Drawing.Point(bb.x1, bb.y2));
                            g.DrawLine(boundingBoxPen, new System.Drawing.Point(bb.x1, bb.y2), new System.Drawing.Point(bb.x2, bb.y2));
                            g.DrawLine(boundingBoxPen, new System.Drawing.Point(bb.x2, bb.y2), new System.Drawing.Point(bb.x2, bb.y1));
                            g.DrawLine(boundingBoxPen, new System.Drawing.Point(bb.x2, bb.y1), new System.Drawing.Point(bb.x1, bb.y1));
                        }

                        for (int marker = 0; marker < permittedMarkerList.Count; marker++)
                        {
                            int markerID = permittedMarkerList[marker].ID;
                            string markerCode = permittedMarkerList[marker].Code;
                            BoundingBox bb = componentFinder.ObjectBoundingBoxes[markerID];
                            g.DrawString(markerCode, markerFont, Brushes.Red, new PointF(bb.x1, bb.y2));
                        }
                    }
                }

                this.workerStatus = WorkerStatus.Finished;
                workerTicks++;
                resetEvent.Reset();
                frameMutex.ReleaseMutex();
            }
        }
        protected override unsafe void ProcessFilter(UnmanagedImage image)
        {
            UnmanagedImage unmanagedBackgroundImage = null;
            BitmapData     bitmapData = null;
            int            width      = image.Width;
            int            height     = image.Height;
            int            num3       = image.Stride - ((image.PixelFormat == PixelFormat.Format8bppIndexed) ? width : (width * 3));

            if ((this.backgroundImage == null) && (this.unmanagedBackgroundImage == null))
            {
                ResizeBicubic  bicubic = new ResizeBicubic(width / 3, height / 3);
                UnmanagedImage image3  = bicubic.Apply(image);
                GaussianBlur   blur    = new GaussianBlur(5.0, 0x15);
                blur.ApplyInPlace(image3);
                blur.ApplyInPlace(image3);
                blur.ApplyInPlace(image3);
                blur.ApplyInPlace(image3);
                blur.ApplyInPlace(image3);
                bicubic.NewWidth         = width;
                bicubic.NewHeight        = height;
                unmanagedBackgroundImage = bicubic.Apply(image3);
                image3.Dispose();
            }
            else if (this.backgroundImage != null)
            {
                if (((width != this.backgroundImage.Width) || (height != this.backgroundImage.Height)) || (image.PixelFormat != this.backgroundImage.PixelFormat))
                {
                    throw new InvalidImagePropertiesException("Source image and background images must have the same size and pixel format");
                }
                bitmapData = this.backgroundImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, this.backgroundImage.PixelFormat);
                unmanagedBackgroundImage = new UnmanagedImage(bitmapData);
            }
            else
            {
                unmanagedBackgroundImage = this.unmanagedBackgroundImage;
            }
            ImageStatistics statistics = new ImageStatistics(unmanagedBackgroundImage);
            byte *          numPtr     = (byte *)image.ImageData.ToPointer();
            byte *          numPtr2    = (byte *)unmanagedBackgroundImage.ImageData.ToPointer();

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                double num4 = statistics.Gray.get_Mean();
                for (int i = 0; i < height; i++)
                {
                    int num6 = 0;
                    while (num6 < width)
                    {
                        if (numPtr2[0] != 0)
                        {
                            numPtr[0] = (byte)Math.Min((double)((num4 * numPtr[0]) / ((double)numPtr2[0])), (double)255.0);
                        }
                        num6++;
                        numPtr++;
                        numPtr2++;
                    }
                    numPtr  += num3;
                    numPtr2 += num3;
                }
            }
            else
            {
                double num7 = statistics.Red.get_Mean();
                double num8 = statistics.Green.get_Mean();
                double num9 = statistics.Blue.get_Mean();
                for (int j = 0; j < height; j++)
                {
                    int num11 = 0;
                    while (num11 < width)
                    {
                        if (numPtr2[2] != 0)
                        {
                            numPtr[2] = (byte)Math.Min((double)((num7 * numPtr[2]) / ((double)numPtr2[2])), (double)255.0);
                        }
                        if (numPtr2[1] != 0)
                        {
                            numPtr[1] = (byte)Math.Min((double)((num8 * numPtr[1]) / ((double)numPtr2[1])), (double)255.0);
                        }
                        if (numPtr2[0] != 0)
                        {
                            numPtr[0] = (byte)Math.Min((double)((num9 * numPtr[0]) / ((double)numPtr2[0])), (double)255.0);
                        }
                        num11++;
                        numPtr  += 3;
                        numPtr2 += 3;
                    }
                    numPtr  += num3;
                    numPtr2 += num3;
                }
            }
            if (this.backgroundImage != null)
            {
                this.backgroundImage.UnlockBits(bitmapData);
            }
            if ((this.backgroundImage == null) && (this.unmanagedBackgroundImage == null))
            {
                unmanagedBackgroundImage.Dispose();
            }
        }
Exemple #14
0
        protected unsafe override void ProcessFilter(UnmanagedImage image)
        {
            UnmanagedImage unmanagedImage = null;
            BitmapData     bitmapData     = null;
            int            width          = image.Width;
            int            height         = image.Height;
            int            num            = image.Stride - ((image.PixelFormat == PixelFormat.Format8bppIndexed) ? width : (width * 3));

            if (backgroundImage == null && unmanagedBackgroundImage == null)
            {
                ResizeBicubic  resizeBicubic   = new ResizeBicubic(width / 3, height / 3);
                UnmanagedImage unmanagedImage2 = resizeBicubic.Apply(image);
                GaussianBlur   gaussianBlur    = new GaussianBlur(5.0, 21);
                gaussianBlur.ApplyInPlace(unmanagedImage2);
                gaussianBlur.ApplyInPlace(unmanagedImage2);
                gaussianBlur.ApplyInPlace(unmanagedImage2);
                gaussianBlur.ApplyInPlace(unmanagedImage2);
                gaussianBlur.ApplyInPlace(unmanagedImage2);
                resizeBicubic.NewWidth  = width;
                resizeBicubic.NewHeight = height;
                unmanagedImage          = resizeBicubic.Apply(unmanagedImage2);
                unmanagedImage2.Dispose();
            }
            else if (backgroundImage != null)
            {
                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");
                }
                bitmapData     = backgroundImage.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, backgroundImage.PixelFormat);
                unmanagedImage = new UnmanagedImage(bitmapData);
            }
            else
            {
                unmanagedImage = unmanagedBackgroundImage;
            }
            ImageStatistics imageStatistics = new ImageStatistics(unmanagedImage);
            byte *          ptr             = (byte *)image.ImageData.ToPointer();
            byte *          ptr2            = (byte *)unmanagedImage.ImageData.ToPointer();

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                double mean = imageStatistics.Gray.Mean;
                for (int i = 0; i < height; i++)
                {
                    int num2 = 0;
                    while (num2 < width)
                    {
                        if (*ptr2 != 0)
                        {
                            *ptr = (byte)System.Math.Min(mean * (double)(int)(*ptr) / (double)(int)(*ptr2), 255.0);
                        }
                        num2++;
                        ptr++;
                        ptr2++;
                    }
                    ptr  += num;
                    ptr2 += num;
                }
            }
            else
            {
                double mean2 = imageStatistics.Red.Mean;
                double mean3 = imageStatistics.Green.Mean;
                double mean4 = imageStatistics.Blue.Mean;
                for (int j = 0; j < height; j++)
                {
                    int num3 = 0;
                    while (num3 < width)
                    {
                        if (ptr2[2] != 0)
                        {
                            ptr[2] = (byte)System.Math.Min(mean2 * (double)(int)ptr[2] / (double)(int)ptr2[2], 255.0);
                        }
                        if (ptr2[1] != 0)
                        {
                            ptr[1] = (byte)System.Math.Min(mean3 * (double)(int)ptr[1] / (double)(int)ptr2[1], 255.0);
                        }
                        if (*ptr2 != 0)
                        {
                            *ptr = (byte)System.Math.Min(mean4 * (double)(int)(*ptr) / (double)(int)(*ptr2), 255.0);
                        }
                        num3++;
                        ptr  += 3;
                        ptr2 += 3;
                    }
                    ptr  += num;
                    ptr2 += num;
                }
            }
            if (backgroundImage != null)
            {
                backgroundImage.UnlockBits(bitmapData);
            }
            if (backgroundImage == null && unmanagedBackgroundImage == null)
            {
                unmanagedImage.Dispose();
            }
        }