Connected components labeling.

The filter performs labeling of objects in the source image. It colors each separate object using different color. The image processing filter treats all none black pixels as objects' pixels and all black pixel as background.

The filter accepts 8 bpp grayscale images and 24/32 bpp color images and produces 24 bpp RGB image.

Sample usage:

// create filter ConnectedComponentsLabeling filter = new ConnectedComponentsLabeling( ); // apply the filter Bitmap newImage = filter.Apply( image ); // check objects count int objectCount = filter.ObjectCount;

Initial image:

Result image:

Inheritance: BaseFilter
コード例 #1
0
ファイル: Preprocessing.cs プロジェクト: Algorithmix/Picasso
 /// <summary>
 /// Lable Connected Components of the scan, Identify unique objects
 /// </summary>
 /// <param name="image">The mask</param>
 /// <returns>A color coded bitmap showing each object in its own color</returns>
 public static int LabelConnectedComponents(ref Bitmap image)
 {
     AForge.Imaging.Filters.ConnectedComponentsLabeling filter = new AForge.Imaging.Filters.ConnectedComponentsLabeling();
     //and apply!
     image = filter.Apply(image);
     //return object count
     return(filter.ObjectCount);
 }
コード例 #2
0
        static void Main(string[] args)
        {
            Threshold thresh = new Threshold(10);
            Median median = new Median(9);
            Erosion3x3 erode = new Erosion3x3();
            Dilatation3x3 dilate = new Dilatation3x3();
            GrahamConvexHull hullFinder = new GrahamConvexHull();
            ConnectedComponentsLabeling ccLabeler = new ConnectedComponentsLabeling();
            BorderFollowing contourFinder = new BorderFollowing();
            GrayscaleToRGB rgb = new GrayscaleToRGB();
            ConvexHullDefects defectFinder = new ConvexHullDefects(10);

            Bitmap img = (Bitmap)Bitmap.FromFile("hand3.jpg");

            Bitmap image = Grayscale.CommonAlgorithms.BT709.Apply(img);
            thresh.ApplyInPlace(image);
            //median.ApplyInPlace(image);
            erode.ApplyInPlace(image);
            dilate.ApplyInPlace(image);

            BlobCounter counter = new BlobCounter(image);
            counter.ObjectsOrder = ObjectsOrder.Area;

            Blob[] blobs = counter.GetObjectsInformation();

            if (blobs.Length > 0)
            {
                counter.ExtractBlobsImage(image, blobs[0], true);

                UnmanagedImage hand = blobs[0].Image;

                var contour = contourFinder.FindContour(hand);

                if (contour.Count() > 0)
                {
                    var initialHull = hullFinder.FindHull(contour);

                    var defects = defectFinder.FindDefects(contour, initialHull);

                    var filteredHull = initialHull.ClusterHullPoints().FilterLinearHullPoints();

                    var palmCenter = defects.Centroid(contour);

                    var wristPoints = filteredHull.SelectWristPoints(defects, contour);

                    Bitmap color = rgb.Apply(hand).ToManagedImage();

                    //BitmapData data = color.LockBits(new Rectangle(0, 0, color.Width, color.Height), ImageLockMode.ReadWrite, color.PixelFormat);
                    //Drawing.Polyline(data, contour, Color.Blue);
                    //Drawing.Polygon(data, filteredHull, Color.Red);
                    //color.UnlockBits(data);

                    Graphics gr = Graphics.FromImage(color);

                    gr.DrawPolygon(new Pen(Brushes.Red, 3), filteredHull.ToPtArray());
                    gr.DrawLines(new Pen(Brushes.Blue, 3), contour.ToPtArray());
                    gr.DrawEllipse(new Pen(Brushes.Red, 3), palmCenter.X - 10, palmCenter.Y - 10, 20, 20);

                    foreach (ConvexityDefect defect in defects)
                    {
                        gr.DrawEllipse(new Pen(Brushes.Green, 6), contour[defect.Point].X - 10, contour[defect.Point].Y - 10, 20, 20);
                    }

                    foreach (AForge.IntPoint pt in filteredHull)
                    {
                        gr.DrawEllipse(new Pen(Brushes.Yellow, 6), pt.X - 10, pt.Y - 10, 20, 20);
                    }

                    foreach (AForge.IntPoint pt in wristPoints)
                    {
                        gr.DrawEllipse(new Pen(Brushes.PowderBlue, 6), pt.X - 10, pt.Y - 10, 20, 20);
                    }

                    ImageBox.Show(color);
                }
            }
        }
コード例 #3
0
ファイル: Preprocessing.cs プロジェクト: Algorithmix/Papyrus
 /// <summary>
 /// Lable Connected Components of the scan, Identify unique objects
 /// </summary>
 /// <param name="image">The mask</param>
 /// <returns>A color coded bitmap showing each object in its own color</returns>
 public static int LabelConnectedComponents(ref Bitmap image)
 {
     AForge.Imaging.Filters.ConnectedComponentsLabeling filter = new AForge.Imaging.Filters.ConnectedComponentsLabeling();
     //and apply!
     image = filter.Apply(image);
     //return object count
     return filter.ObjectCount;
 }
コード例 #4
0
        private void cameraTask_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(e.ChosenPhoto);
                bmp.ImageOpened += ImageOpenedTrue;
                //imgPreview.Source = bmp;
                //bmp.DecodePixelHeight = 460;
                //Height="460" Margin="10,10,0,0" VerticalAlignment="Top" Width="684">
                WriteableBitmap wbmp = new WriteableBitmap(bmp);
                //txtImage.Text = "Korkeus: " + wbmp.PixelHeight + " Leveys: " + wbmp.PixelWidth;
                Bitmap image = (Bitmap)wbmp;
                //AForge.Imaging.Filters.Grayscale
                //Grayscale gs = new Grayscale(

                // create filter
                ResizeNearestNeighbor filter = new ResizeNearestNeighbor(700, 480);
                // apply the filter
                Bitmap resizeImage = filter.Apply(image);
                txtImage.Text = "Korkeus: " + resizeImage.Height + " Leveys: " + resizeImage.Width;
                // create grayscale filter (BT709)
                Grayscale GSfilter = new Grayscale(0.2125, 0.7154, 0.0721);
                // apply the filter
                Bitmap grayImage = GSfilter.Apply(resizeImage);

                // create filter
                Threshold BIfilter = new Threshold(70);
                // apply the filter
                BIfilter.ApplyInPlace(grayImage);

                // create filter
                Invert Invertfilter = new Invert();
                // apply the filter
                Invertfilter.ApplyInPlace(grayImage);

                AForge.Imaging.Filters.ConnectedComponentsLabeling Blobfilter = new AForge.Imaging.Filters.ConnectedComponentsLabeling();
                Bitmap      newImage    = Blobfilter.Apply(grayImage);
                BlobCounter blobCounter = new BlobCounter(newImage);
                blobCounter.FilterBlobs = true;
                blobCounter.MinWidth    = 5;
                blobCounter.MinHeight   = 5;
                Blob[] blobs = blobCounter.GetObjectsInformation();
                gos = new List <GameObject>();
                List <Blob>     blobList          = blobs.ToList();
                PointCollection extremePoints     = new PointCollection();
                System.Windows.Shapes.Rectangle r = new System.Windows.Shapes.Rectangle();
                PointCollection        edges;
                List <AForge.IntPoint> lst;
                List <int[]>           intlist = new List <int[]>();
                GameObject             go      = new GameObject();
                foreach (Blob b in blobs)
                {
                    lst   = blobCounter.GetBlobsEdgePoints(b);
                    edges = new PointCollection();
                    foreach (AForge.IntPoint p in lst)
                    {
                        edges.Add(new System.Windows.Point(p.X, p.Y));
                    }

                    /*
                     * extremePoints.Add(new System.Windows.Point(b.Rectangle.X, b.Rectangle.Y));
                     * extremePoints.Add(new System.Windows.Point(b.Rectangle.X+b.Rectangle.Width, b.Rectangle.Y));
                     * extremePoints.Add(new System.Windows.Point(b.Rectangle.X, b.Rectangle.Y+b.Rectangle.Height));
                     * extremePoints.Add(new System.Windows.Point(b.Rectangle.X + b.Rectangle.Width, b.Rectangle.Y + b.Rectangle.Height));
                     * */
                    gos.Add(new GameObject(b.Rectangle.Y, b.Rectangle.X, b.Rectangle.Width, b.Rectangle.Height, edges)); // x ja y käännettynä, jotta lopullisessa mallissa suunnat oikein.
                    //GameObject go = new GameObject(
                    //extremePoints.Clear();
                    //edges.Clear();
                }
                //Serialize("LevelName.bin", gos);
                //SaveToLocalFolderAsync(e.ChosenPhoto, "LevelNameBG.jpg");
                //writeJsonAsync();
                fileName = txtBoxLevelName.Text;
                jsonWrite(fileName);
                WriteableBitmap wb;
                wb = (WriteableBitmap)resizeImage;

                using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (iso.FileExists(fileName + "_bg.jpg"))
                    {
                        iso.DeleteFile(fileName + "_bg.jpg");
                    }
                    using (IsolatedStorageFileStream isostream = iso.CreateFile(fileName + "_bg.jpg"))
                    {
                        Extensions.SaveJpeg(wb, isostream, wb.PixelWidth, wb.PixelHeight, 0, 85);
                        isostream.Close();
                    }
                }

                //Rectangle[] rects = blobCounter.GetObjectsRectangles();
                //txtImage.Text = txtImage.Text + "Number of rectangles:+ " + rects.Length;

                wbmp = (WriteableBitmap)newImage;

                imgImage.Source = wbmp;
                // BY PIXEL

                /*
                 * foreach (int pix in wbmp.Pixels)
                 * {
                 *  int a = pix >> 24;
                 *  int r = (pix & 0x00ff0000) >> 16;
                 *  int g = (pix & 0x0000ff00) >> 8;
                 *  int b = (pix & 0x000000ff);
                 *  Color c = new Color(r, g, b, a);
                 *  int intensity = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
                 *  if (intensity > 127) ; // BLACK / SOLID
                 *  else ; // WHITE / NON-SOLID
                 * }*/
                //byte[] baLevel = CustomConvertToBytes(bmp);

                /*
                 * WriteableBitmap wbmp = new WriteableBitmap(bmp as BitmapSource);
                 * imgPreview.Source = wbmp;*/
            }
        }
コード例 #5
0
        private void cameraTask_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                
                BitmapImage bmp = new BitmapImage();
                bmp.SetSource(e.ChosenPhoto);
                bmp.ImageOpened += ImageOpenedTrue;
                //imgPreview.Source = bmp;
                //bmp.DecodePixelHeight = 460;
                //Height="460" Margin="10,10,0,0" VerticalAlignment="Top" Width="684">
                WriteableBitmap wbmp = new WriteableBitmap(bmp);
                //txtImage.Text = "Korkeus: " + wbmp.PixelHeight + " Leveys: " + wbmp.PixelWidth;
                Bitmap image = (Bitmap)wbmp;
                //AForge.Imaging.Filters.Grayscale
                //Grayscale gs = new Grayscale(

                // create filter
                ResizeNearestNeighbor filter = new ResizeNearestNeighbor(700, 480);
                // apply the filter
                Bitmap resizeImage = filter.Apply(image);
                txtImage.Text = "Korkeus: " + resizeImage.Height + " Leveys: " + resizeImage.Width;
                // create grayscale filter (BT709)
                Grayscale GSfilter = new Grayscale(0.2125, 0.7154, 0.0721);
                // apply the filter
                Bitmap grayImage = GSfilter.Apply(resizeImage);

                // create filter
                Threshold BIfilter = new Threshold(70);
                // apply the filter
                BIfilter.ApplyInPlace(grayImage);

                // create filter
                Invert Invertfilter = new Invert();
                // apply the filter
                Invertfilter.ApplyInPlace(grayImage);

                AForge.Imaging.Filters.ConnectedComponentsLabeling Blobfilter = new AForge.Imaging.Filters.ConnectedComponentsLabeling();
                Bitmap newImage = Blobfilter.Apply(grayImage);
                BlobCounter blobCounter = new BlobCounter(newImage);
                blobCounter.FilterBlobs = true;
                blobCounter.MinWidth = 5;
                blobCounter.MinHeight = 5;
                Blob[] blobs = blobCounter.GetObjectsInformation();
                gos = new List<GameObject>();
                List<Blob> blobList = blobs.ToList();
                PointCollection extremePoints = new PointCollection();
                System.Windows.Shapes.Rectangle r = new System.Windows.Shapes.Rectangle();
                PointCollection edges;
                List<AForge.IntPoint> lst;
                List<int[]> intlist = new List<int[]>();
                GameObject go = new GameObject();
                foreach (Blob b in blobs)
                {
                    lst = blobCounter.GetBlobsEdgePoints(b);
                    edges = new PointCollection();
                    foreach (AForge.IntPoint p in lst)
                    {
                        edges.Add(new System.Windows.Point(p.X, p.Y));
                    }
                    /*
                    extremePoints.Add(new System.Windows.Point(b.Rectangle.X, b.Rectangle.Y));
                    extremePoints.Add(new System.Windows.Point(b.Rectangle.X+b.Rectangle.Width, b.Rectangle.Y));
                    extremePoints.Add(new System.Windows.Point(b.Rectangle.X, b.Rectangle.Y+b.Rectangle.Height));
                    extremePoints.Add(new System.Windows.Point(b.Rectangle.X + b.Rectangle.Width, b.Rectangle.Y + b.Rectangle.Height));
                     * */
                    gos.Add(new GameObject(b.Rectangle.Y,b.Rectangle.X,b.Rectangle.Width,b.Rectangle.Height,edges)); // x ja y käännettynä, jotta lopullisessa mallissa suunnat oikein.
                    //GameObject go = new GameObject(
                    //extremePoints.Clear();
                    //edges.Clear();
                }
                //Serialize("LevelName.bin", gos);
                //SaveToLocalFolderAsync(e.ChosenPhoto, "LevelNameBG.jpg");
                //writeJsonAsync();
                fileName = txtBoxLevelName.Text;
                jsonWrite(fileName);
                WriteableBitmap wb;
                wb = (WriteableBitmap)resizeImage;

                using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (iso.FileExists(fileName+"_bg.jpg"))
                    {
                        iso.DeleteFile(fileName+"_bg.jpg");
                    }
                    using (IsolatedStorageFileStream isostream = iso.CreateFile(fileName+"_bg.jpg"))
                    {
                        Extensions.SaveJpeg(wb, isostream, wb.PixelWidth, wb.PixelHeight, 0, 85);
                        isostream.Close(); 
                    }
                }

                //Rectangle[] rects = blobCounter.GetObjectsRectangles();
                //txtImage.Text = txtImage.Text + "Number of rectangles:+ " + rects.Length;

                wbmp = (WriteableBitmap)newImage;

                imgImage.Source = wbmp;
                // BY PIXEL
                /*
                foreach (int pix in wbmp.Pixels)
                {
                    int a = pix >> 24;
                    int r = (pix & 0x00ff0000) >> 16;
                    int g = (pix & 0x0000ff00) >> 8;
                    int b = (pix & 0x000000ff);
                    Color c = new Color(r, g, b, a);
                    int intensity = (int)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
                    if (intensity > 127) ; // BLACK / SOLID
                    else ; // WHITE / NON-SOLID
                }*/
                //byte[] baLevel = CustomConvertToBytes(bmp);
                /*
                WriteableBitmap wbmp = new WriteableBitmap(bmp as BitmapSource);
                imgPreview.Source = wbmp;*/
            }
        }
コード例 #6
0
        public void MagiCalc(double sensor)
        {
            // get image from LiveView
            LiveViewData = SelectedCameraDevice.GetLiveViewImage();

            MemoryStream stream = new MemoryStream(LiveViewData.ImageData,
                        LiveViewData.
                            ImageDataPosition,
                        LiveViewData.ImageData.
                            Length -
                        LiveViewData.
                            ImageDataPosition);

            using (var tempImage = new Bitmap(stream))
            {
                Bitmap bmp = tempImage;
        

                var preview = BitmapFactory.ConvertToPbgra32Format(
                    BitmapSourceConvert.ToBitmapSource(bmp));



                Bitmap binaryimage = bmp;

                // binarize the image to BinaryImage
                
                short[,] se = new short[,] {
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 },
                {  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1 }
                };


                var filter = new FiltersSequence(
                                Grayscale.CommonAlgorithms.BT709,
                                new Threshold(100),
                                new Closing(se),
                                new Opening(se),
                                new Opening(se),
                                new Opening(se),
                                new Invert()
                                );
                binaryimage = filter.Apply(bmp);

                // Pass ConnectedComponentsLabeling Filter
                WriteableBitmap writeableBitmap;

                // Pass ConnectedComponentsLabeling Filter
                ConnectedComponentsLabeling filter2 = new ConnectedComponentsLabeling();
                writeableBitmap = BitmapFactory.ConvertToPbgra32Format(BitmapSourceConvert.ToBitmapSource(filter2.Apply(binaryimage)));

                // Check objects count
                int objectCount = filter2.ObjectCount;
                StepperManager.Instance.LinesNumber = objectCount;

                writeableBitmap.Freeze();
                ColorBitmapSource = writeableBitmap;


                // Calc Magnification
                double one_one;
                one_one = 59 * sensor;

                double _magni;
                _magni = one_one / (objectCount);

                double _Magni = Math.Round(_magni, 1, MidpointRounding.AwayFromZero); //Rounds"up"

                StepperManager.Instance.Magni = _Magni;
            }
            return;
        }
コード例 #7
0
ファイル: Webcam.cs プロジェクト: nakibli/MouseCam
        void webcam_ImageCaptured_Back(object source, WebcamEventArgs e)
        {
            _FrameImage.Image = e.WebCamImage;
            Bitmap MaskImage = new Bitmap(640, 480);
            if (backgroundFrame == null)
            {
                Frames2Ignore--;
                if (Frames2Ignore == 0)
                {
                    backgroundFrame = (Bitmap)e.WebCamImage;
                    backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
                }
                return;
            }

            //Save curent image
            CurrentFrame = (Bitmap)e.WebCamImage;
            CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame);

            /*
            // create filter
            IFilter pixellateFilter = new Pixellate();
            // apply the filter
            backgroundFrame = pixellateFilter.Apply(backgroundFrame);
            backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
            CurrentFrame = pixellateFilter.Apply(CurrentFrame);
            CurrentFrameGray = grayscaleFilter.Apply(CurrentFrame);*/

            MoveTowards moveTowardsFilter = new MoveTowards();
            moveTowardsFilter.OverlayImage = CurrentFrameGray;
            // move background towards current frame
            Bitmap tmp = moveTowardsFilter.Apply(backgroundFrameGray);
            // dispose old background
            backgroundFrame.Dispose();
            backgroundFrame = tmp;

            // create processing filters sequence

            FiltersSequence processingFilter = new FiltersSequence();
            processingFilter.Add(new Difference(backgroundFrameGray));
            processingFilter.Add(new Threshold(15));
            processingFilter.Add(new Opening());
            processingFilter.Add(new Edges());
            processingFilter.Add(new DifferenceEdgeDetector());

            // apply the filter

            Bitmap tmp1 = processingFilter.Apply(CurrentFrameGray);
            // extract red channel from the original image

            IFilter extrachChannel = new ExtractChannel(RGB.R);
            Bitmap redChannel = extrachChannel.Apply(backgroundFrame);

            //  merge red channel with moving object borders

            Merge mergeFilter = new Merge();
            mergeFilter.OverlayImage = tmp1;
            Bitmap tmp2 = mergeFilter.Apply(redChannel);
            // replace red channel in the original image

            ReplaceChannel replaceChannel = new ReplaceChannel(RGB.R,tmp2);
            replaceChannel.ChannelImage = tmp2;
            Bitmap tmp3 = replaceChannel.Apply(backgroundFrame);

            ConnectedComponentsLabeling CCL = new ConnectedComponentsLabeling();
            CCL.MinWidth = 75;
            CCL.MinHeight = 75;
            CCL.CoupledSizeFiltering = true;
            Bitmap tmp4 = CCL.Apply(tmp1);

            blobCounter.MinHeight = 75;
            blobCounter.MinWidth = 75;
            blobCounter.CoupledSizeFiltering = true;
            blobCounter.ProcessImage(tmp1);
            Blob[] blobs = blobCounter.GetObjects(tmp1);
            int maxSize = 0;
            Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0));
            // find biggest blob
            Bitmap Masked = new Bitmap(320, 240);
            if (blobs != null)
            {
                foreach (Blob blob in blobs)
                {
                    int blobSize = blob.Rectangle.Width * blob.Rectangle.Height;

                    if (blobSize > maxSize)
                    {
                        maxSize = blobSize;
                        maxObject = blob;
                    }
                }

                for (int i = maxObject.Rectangle.Left; i < maxObject.Rectangle.Right; i++)
                {
                    for (int j = maxObject.Rectangle.Top; j < maxObject.Rectangle.Bottom; j++)
                    {
                        Masked.SetPixel(i, j, maxObject.Image.GetPixel(i - maxObject.Rectangle.Left, j - maxObject.Rectangle.Top));
                    }
                }
            }

            /*Bitmap Hor = new Bitmap(320, 240);
            Bitmap Ver = new Bitmap(320, 240);
            if (maxSize > 150)
            {
                AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(tmp1);
                int[] HistVer = VIS.Gray.Values;
                AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(tmp1);
                int[] HistHor = HIS.Gray.Values;

                for (int x=0;x<320;x++)
                    for (int y = 0; y < 240; y++)
                    {
                        Hor.SetPixel(x, y, Color.White);
                        Ver.SetPixel(x, y, Color.White);
                    }
                int Imax = -1, Max = -1;
                for (int i = 0; i < HistHor.Length; i++)
                {
                    for (int y = 0; y < ((double)(HistHor[i]) / 255) ; y++)
                        Hor.SetPixel(i, y, Color.Black);
                        if (HistHor[i] > 0)
                        {
                            Imax = i;
                            Max = HistHor[i];
                        }
                }
                int ImaxY = -1, MaxY = -1;
                for (int i = 0; i < HistVer.Length; i++)
                {
                    for (int x = 0; x < ((double)(HistVer[i]) / 255) ; x++)
                        Ver.SetPixel(x, i, Color.Black);
                    if (HistVer[i] > MaxY)
                    {
                        ImaxY = i;
                        MaxY = HistVer[i];
                    }
                }
            }

            */
               /* blobCounter.MinHeight = 75;
            blobCounter.MinWidth = 75;
            blobCounter.CoupledSizeFiltering = true;
            blobCounter.ProcessImage(tmp1);

            Blob[] blobs = blobCounter.GetObjects(tmp1);
            int maxSize = 0;
            Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0));
            // find biggest blob
            if (blobs != null)
            {
                foreach (Blob blob in blobs)
                {
                    int blobSize = blob.Rectangle.Width * blob.Rectangle.Height;

                    if (blobSize > maxSize)
                    {
                        maxSize = blobSize;
                        maxObject = blob;
                    }
                }

                if (maxObject.Rectangle.Height > 90 && maxObject.Rectangle.Width > 30)
                {
                    AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(maxObject.Image);
                    int[] HistVer = VIS.Gray.Values;
                    AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(maxObject.Image);
                    int[] HistHor = HIS.Gray.Values;

                    int Imax = -1, Max = -1;
                    for (int i = 0; i < HistHor.Length; i++)
                    {
                        if (HistHor[i] > 0)
                        {
                            Imax = i;
                            Max = HistHor[i];
                            break;
                        }
                    }
                    int ImaxY = -1, MaxY = -1;
                    for (int i = 0; i < HistVer.Length; i++)
                    {
                        if (HistVer[i] > MaxY)
                        {
                            ImaxY = i;
                            MaxY = HistVer[i];
                        }
                    }
                    //Imax = 0;
                    ImaxY = 0;

                    Console.WriteLine("X={0},Y={1}", maxObject.Rectangle.X, maxObject.Rectangle.Y);
                    if (eChangedCursorEvent != null && maxSize != 0)
                        eChangedCursorEvent(maxObject.Rectangle.X + Imax, maxObject.Rectangle.Y + ImaxY);
                    LastX = maxObject.Rectangle.X;
                    LastY = maxObject.Rectangle.Y;
                }*/
                /*else if (LastX != -1 && LastY != -1 && maxSize > 0)
                {
                    //Calc distance from LastX,LastY
                    double distX = System.Math.Pow(maxObject.Rectangle.X - LastX, 2);
                    double distY = System.Math.Pow(maxObject.Rectangle.Y - LastY, 2);
                    double dist = System.Math.Pow(distX + distY, 0.5);
                    if (dist < 15)
                    {
                        Console.WriteLine("X={0},Y={1}", maxObject.Rectangle.X, maxObject.Rectangle.Y);
                        if (eChangedCursorEvent != null && maxSize != 0)
                            eChangedCursorEvent(maxObject.Rectangle.X, maxObject.Rectangle.Y);
                        LastX = maxObject.Rectangle.X;
                        LastY = maxObject.Rectangle.Y;
                    }
                    else
                    {
                        LastX = -1;
                        LastY = -1;
                    }
                }
                else
                {
                    LastX = -1;
                    LastY = -1;
                }*/
            //}
            _CaptureImage.Image = maxObject.Image;
            //_CaptureImage.Image = tmp3;
            _CaptureImage2.Image = tmp4;
            backgroundFrame = (Bitmap)e.WebCamImage;
            backgroundFrameGray = grayscaleFilter.Apply(backgroundFrame);
        }