Example #1
0
        private String ContainGreen(Bitmap bitmap)
        {
            HSLFiltering filter = new HSLFiltering();

            // set color ranges to keep
            filter.Hue        = new IntRange(80, 150);
            filter.Saturation = new Range(0.4f, 1);
            filter.Luminance  = new Range(0.2f, 0.7f);
            filter.ApplyInPlace(bitmap);
            AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter();
            blobCounterGreen.FilterBlobs  = true;
            blobCounterGreen.ObjectsOrder = ObjectsOrder.Area;
            blobCounterGreen.MinHeight    = 10;
            blobCounterGreen.MinWidth     = 10;
            blobCounterGreen.ProcessImage(bitmap);
            //capturedPhotoGreen.Source = (WriteableBitmap)bitmap;
            AForge.Imaging.Blob[] blobsGreen = blobCounterGreen.GetObjectsInformation();
            for (int iBlob = 0; iBlob < blobsGreen.Length; iBlob++)
            {
                for (int jBlob = iBlob + 1; jBlob < blobsGreen.Length; jBlob++)
                {
                    if ((Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) < blobsGreen[iBlob].Rectangle.Width / 2) &&
                        (Math.Abs(blobsGreen[iBlob].CenterOfGravity.Y - blobsGreen[jBlob].CenterOfGravity.Y) < 3 * blobsGreen[iBlob].Rectangle.Height) &&
                        (Math.Abs(blobsGreen[iBlob].Area - blobsGreen[jBlob].Area) < blobsGreen[iBlob].Area / 2))
                    {
                        //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) + "w" + blobsGreen[iBlob].Rectangle.Width / 2; }
                        //catch (Exception ex) { text_log.Text = ex + ""; }
                        return("Green");
                    }
                }
            }
            //text_log.Text += "nG";
            return("");
        }
        public override void calcDescriptorInfo(Bitmap inImage)
        {
            shapeCount = new int[6];

            originalImage = image;
            image = imgProcessor.preProcessImage(inImage);

            g = Graphics.FromImage(originalImage);

            BlobCounter bCounter = new BlobCounter();
            bCounter.ProcessImage(image);
            Blob[] blobs = bCounter.GetObjectsInformation();

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            for (int i = 0; i < blobs.Length; i++)
            {
                if (blobs[i].Area < 100)
                {
                    continue;
                }
                List<IntPoint> edgePts = bCounter.GetBlobsEdgePoints(blobs[i]);
                checkShape(shapeChecker, edgePts);

            }

            g.Dispose();
        }
Example #3
0
        public void DetectShapes()
        {
            int       count                    = 40;
            int       minSize                  = 5;
            int       maxSize                  = 80;
            var       image                    = (Bitmap)Image.FromFile(@"C:\Users\marco\Downloads\PanoBeam\capture_pattern0.png");
            Rectangle clippingRectangle        = new Rectangle(new Point(563, 360), new Size(1156, 382));
            var       clippingRectangleCorners = new[]
            {
                new AForge.IntPoint(clippingRectangle.X, clippingRectangle.Y),
                new AForge.IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y),
                new AForge.IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y + clippingRectangle.Height),
                new AForge.IntPoint(clippingRectangle.X, clippingRectangle.Y + clippingRectangle.Height)
            };

            Helpers.FillOutsideBlack(image, clippingRectangleCorners);

            var blobCounter = new AForge.Imaging.BlobCounter();

            AForge.Imaging.Blob[] blobs;
            blobCounter.FilterBlobs = true;
            blobCounter.MaxHeight   = maxSize;
            blobCounter.MaxWidth    = maxSize;
            blobCounter.MinHeight   = minSize;
            blobCounter.MinWidth    = minSize;

            var threshold = Recognition.GetThreshold(image);

            blobCounter.BackgroundThreshold = Color.FromArgb(255, threshold, threshold, threshold);
            blobCounter.ProcessImage(image);
            blobs = blobCounter.GetObjectsInformation();
        }
Example #4
0
        private String ContainBlue(Bitmap bitmap)
        {
            HSLFiltering blueFilter = new HSLFiltering();

            blueFilter.Hue        = new IntRange(150, 210);
            blueFilter.Saturation = new Range(0.3f, 1);
            blueFilter.Luminance  = new Range(0.20f, 0.8f);
            blueFilter.ApplyInPlace(bitmap);


            AForge.Imaging.BlobCounter blobCounterBlue = new AForge.Imaging.BlobCounter();
            blobCounterBlue.FilterBlobs  = true;
            blobCounterBlue.ObjectsOrder = ObjectsOrder.Area;
            blobCounterBlue.MinHeight    = 10;
            blobCounterBlue.MinWidth     = 10;
            blobCounterBlue.ProcessImage(bitmap);
            //capturedPhotoBlue.Source = (WriteableBitmap)bitmap;
            AForge.Imaging.Blob[] blobsBlue = blobCounterBlue.GetObjectsInformation();
            for (int iBlob = 0; iBlob < blobsBlue.Length; iBlob++)
            {
                for (int jBlob = iBlob + 1; jBlob < blobsBlue.Length; jBlob++)
                {
                    if ((Math.Abs(blobsBlue[iBlob].CenterOfGravity.X - blobsBlue[jBlob].CenterOfGravity.X) < blobsBlue[iBlob].Rectangle.Width / 2) &&
                        (Math.Abs(blobsBlue[iBlob].CenterOfGravity.Y - blobsBlue[jBlob].CenterOfGravity.Y) < 3 * blobsBlue[iBlob].Rectangle.Height) &&
                        (Math.Abs(blobsBlue[iBlob].Area - blobsBlue[jBlob].Area) < blobsBlue[iBlob].Area / 2))
                    {
                        //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsBlue[iBlob].CenterOfGravity.X - blobsBlue[jBlob].CenterOfGravity.X) + "w" + blobsBlue[iBlob].Rectangle.Width / 2; }
                        //catch (Exception ex) { text_log.Text = ex + ""; }
                        return("Blue");
                    }
                }
            }

            return("");
        }
Example #5
0
        private void colorOfPlayer(Bitmap bitmap)
        {
            HSLFiltering GreenFilter = new HSLFiltering();

            GreenFilter.Hue        = new IntRange(200, 250);
            GreenFilter.Saturation = new Range(0.5f, 1);
            GreenFilter.Luminance  = new Range(0.2f, 0.6f);
            GreenFilter.ApplyInPlace(bitmap);
            wbt             = (WriteableBitmap)bitmap;
            img2.Source     = wbt;
            img2.Visibility = Visibility.Visible;
            //    this.PictureBox.Source = (ImageSource)concatenate.Apply(this.img2);

            BlobCounter blobCounter = new AForge.Imaging.BlobCounter();

            blobCounter.ObjectsOrder = ObjectsOrder.Area;
            blobCounter.FilterBlobs  = true;
            blobCounter.MinHeight    = 10;
            blobCounter.MinWidth     = 10;
            blobCounter.ProcessImage(bitmap);
            Blob[]             blobs        = blobCounter.GetObjectsInformation();
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();


            try {
                for (int i = 0, n = blobs.Length; i < n; i++)
                {
                    List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                    AForge.Point    center;
                    float           radius;
                    // is circle ?
                    if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                    {
                        if ((blobs[i].Area < 17000) && (blobs[i].Area > 3000))
                        {
                            score = score + 2;
                        }
                        else if ((blobs[i].Area < 3000) && (blobs[i].Area > 1300))
                        {
                            score = score + 4;
                        }
                        else if (blobs[i].Area < 1300)
                        {
                            score = score + 6;
                        }
                    }
                }
            }catch (Exception eeeee)
            {
            }

            text_score.Text = "" + score;
        }
Example #6
0
        /// <summary>
        /// Celem metody jest przykadrowanie otrzymanego obrazka, tak aby widok zawierał jedynie kartkę papieru, oraz zwrócenie go do metody UploadFile
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public System.Drawing.Image CropImage(System.Drawing.Image img)
        {
            //DocumentSkewChecker skewChecker = new DocumentSkewChecker();
            //double angle = skewChecker.GetSkewAngle(image);
            //RotateBilinear rotationFilter = new RotateBilinear(-angle);
            //rotationFilter.FillColor = Color.White;
            //Bitmap rotatedImage = rotationFilter.Apply(image);

            Bitmap image = new Bitmap(img);

            UnmanagedImage grayImage = null;

            if (image.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                grayImage = UnmanagedImage.FromManagedImage(image);
            }
            else
            {
                grayImage = UnmanagedImage.Create(image.Width, image.Height,
                    PixelFormat.Format8bppIndexed);
                Grayscale.CommonAlgorithms.BT709.Apply(UnmanagedImage.FromManagedImage(image), grayImage);
            }

            CannyEdgeDetector edgeDetector = new CannyEdgeDetector();
            UnmanagedImage edgesImage = edgeDetector.Apply(grayImage);

            OtsuThreshold thresholdFilter = new OtsuThreshold();
            thresholdFilter.ApplyInPlace(edgesImage);

            Dilatation DilatationFilter = new Dilatation();
            DilatationFilter.Apply(edgesImage);

            Opening OpeningFilter = new Opening();
            OpeningFilter.Apply(edgesImage);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.MinHeight = 32;
            blobCounter.MinWidth = 32;
            blobCounter.FilterBlobs = true;
            blobCounter.ObjectsOrder = ObjectsOrder.Size;

            blobCounter.ProcessImage(edgesImage);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            ExtractBiggestBlob BiggestBlob = new ExtractBiggestBlob();
            Bitmap biggestBlobsImage = BiggestBlob.Apply(edgesImage.ToManagedImage());
            AForge.IntPoint BiggestBlogCorners = BiggestBlob.BlobPosition;

            Crop cropFilter = new Crop(new Rectangle(BiggestBlogCorners.X, BiggestBlogCorners.Y, biggestBlobsImage.Width, biggestBlobsImage.Height));
            Bitmap croppedImage = cropFilter.Apply(image);
            return croppedImage;
        }
Example #7
0
        private Boolean colorOfPlayer(Bitmap bitmap)
        {
            Boolean ok = false;

            HSLFiltering filterRed = new HSLFiltering();

            filterRed.Hue        = new IntRange(301, 9);   //red at night (334, 40)
            filterRed.Saturation = new Range(0.4f, 1);     //0.55
            filterRed.Luminance  = new Range(0.1f, 0.68f); //75
            filterRed.ApplyInPlace(bitmap);

            AForge.Imaging.BlobCounter blobCounterRed = new AForge.Imaging.BlobCounter();
            blobCounterRed.FilterBlobs  = true;
            blobCounterRed.ObjectsOrder = ObjectsOrder.Area;
            blobCounterRed.MinHeight    = 10;
            blobCounterRed.MinWidth     = 10;
            try { blobCounterRed.ProcessImage(bitmap); } catch (Exception es) { gameUpdate.Text = "filter"; }


            AForge.Imaging.Blob[] blobsRed = blobCounterRed.GetObjectsInformation();
            //Mean filter = new Mean();
            //// apply the filter
            //filter.ApplyInPlace(bitmap);
            bool fin = false;

            try
            {
                for (int iBlob = 0; iBlob < blobsRed.Length; iBlob++)
                {
                    for (int jBlob = iBlob + 1; jBlob < blobsRed.Length; jBlob++)
                    {
                        if ((Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) < blobsRed[iBlob].Rectangle.Width / 2) &&
                            (Math.Abs(blobsRed[iBlob].CenterOfGravity.Y - blobsRed[jBlob].CenterOfGravity.Y) < 3 * blobsRed[iBlob].Rectangle.Height) &&
                            (Math.Abs(blobsRed[iBlob].Area - blobsRed[jBlob].Area) < blobsRed[iBlob].Area / 2))
                        {
                            // gameUpdate.Text = "OK" + SharedInformation.myNumber + getPlayerNumberByColor("Red");
                            ortcExample.DoSendMessage(SharedInformation.myNumber + getPlayerNumberByColor("Red"));
                            fin = true;
                            return(true);
                        }
                    }
                    if (fin)
                    {
                        break;
                    }
                }
            }
            catch (Exception es) {
                gameUpdate.Text = "erreur";
            }
            return(ok);
        }
Example #8
0
        private void colorOfPlayer2(Bitmap bitmap2)
        {
            Bitmap bit2 = null;

            bit2 = bitmap2;
            bool         fin    = false;
            HSLFiltering filter = new HSLFiltering();

            // set color ranges to keep
            filter.Hue        = new IntRange(150, 210);
            filter.Saturation = new Range(0.3f, 1);
            filter.Luminance  = new Range(0.20f, 0.8f);
            filter.ApplyInPlace(bit2);
            AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter();
            blobCounterGreen.FilterBlobs  = true;
            blobCounterGreen.ObjectsOrder = ObjectsOrder.Area;
            blobCounterGreen.MinHeight    = 10;
            blobCounterGreen.MinWidth     = 10;
            blobCounterGreen.ProcessImage(bit2);

            AForge.Imaging.Blob[] blobsGreen = blobCounterGreen.GetObjectsInformation();


            try
            {
                for (int iBlob = 0; iBlob < blobsGreen.Length; iBlob++)
                {
                    for (int jBlob = iBlob + 1; jBlob < blobsGreen.Length; jBlob++)
                    {
                        if ((Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) < blobsGreen[iBlob].Rectangle.Width / 2) &&
                            (Math.Abs(blobsGreen[iBlob].CenterOfGravity.Y - blobsGreen[jBlob].CenterOfGravity.Y) < 3 * blobsGreen[iBlob].Rectangle.Height) &&
                            (Math.Abs(blobsGreen[iBlob].Area - blobsGreen[jBlob].Area) < blobsGreen[iBlob].Area / 2))
                        {
                            //gameUpdate.Text = "OK" + SharedInformation.myNumber + getPlayerNumberByColor("Blue");
                            ortcExample.DoSendMessage(SharedInformation.myNumber + getPlayerNumberByColor("Blue"));
                            fin = true;
                            break;
                        }
                    }
                    if (fin)
                    {
                        break;
                    }
                }
            }
            catch (Exception es)
            {
                gameUpdate.Text = "erreur22";
            }
        }
 // 如果活动返回值,则从 CodeActivity<TResult>
 // 派生并从 Execute 方法返回该值。
 protected override void Execute(CodeActivityContext context)
 {
     // create an instance of blob counter algorithm
     BlobCounterBase bc = new BlobCounter();
     // set filtering options
     bc.FilterBlobs = true;
     bc.MinWidth = context.GetValue(最小宽度);
     bc.MinHeight = context.GetValue(最小高度);
     // set ordering options
     bc.ObjectsOrder = ObjectsOrder.Size;
     // process binary image
     bc.ProcessImage(context.GetValue(处理目标));
     var blobs = bc.GetObjectsInformation();
     context.SetValue(输出目标, blobs);
 }
Example #10
0
        public static void Rectangle(WriteableBitmap bitmap, DrawingContext dc)
        {
            // locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MaxHeight = 375;
            blobCounter.MaxWidth = 375;
            System.Drawing.Bitmap image;
            using (var stream = new MemoryStream())
            {
                var encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bitmap));
                encoder.Save(stream);
                image = new System.Drawing.Bitmap(stream);
            }
            blobCounter.ProcessImage(image);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // check for rectangles
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            foreach (var blob in blobs)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);
                List<IntPoint> cornerPoints;

                // use the shape checker to extract the corner points
                if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
                {
                    // only do things if the corners form a rectangle
                    if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle)
                    {
                        // here i use the graphics class to draw an overlay, but you
                        // could also just use the cornerPoints list to calculate your
                        // x, y, width, height values.
                        List<AForge.Point> Points = new List<AForge.Point>();
                        foreach (var point in cornerPoints)
                        {
                            Points.Add(new AForge.Point(point.X, point.Y));
                        }
                        var path = new PathFigure(new System.Windows.Point(Points.First().X, Points.First().Y), Points.Select(row => new System.Windows.Media.LineSegment(new System.Windows.Point(row.X, row.Y), false)), true);

                        dc.DrawGeometry(Brushes.Red, null, new PathGeometry(new PathFigure[] { path }));
                    }
                }
            }
        }
Example #11
0
        public IEnumerable<Bitmap> Apply(Bitmap bitmap)
        {
            // assuming scanned background is white we need to invert for the algo to work
            var copy = new Invert().Apply(bitmap);

            copy = EnsureGrayscale(copy);
            new Threshold { ThresholdValue = 25 }.ApplyInPlace(copy);
            new FillHoles().ApplyInPlace(copy);

            var blobCounter = new BlobCounter
            {
                // set filtering options
                FilterBlobs = true,
                MinWidth = 50,
                MinHeight = 50,
            };

            blobCounter.ProcessImage(copy);
            var blobs = blobCounter.GetObjectsInformation();

            if (blobs.Any())
            {
                var invertedOriginal = new Invert().Apply(bitmap);
                foreach (var blob in blobs)
                {
                    // use inverted source to ensure correct edge colors
                    blobCounter.ExtractBlobsImage(invertedOriginal, blob, false);
                    var blobImage = blob.Image.ToManagedImage();

                    // straighten
                    var angle = new DocumentSkewChecker().GetSkewAngle(EnsureGrayscale(blobImage));
                    var rotationFilter = new RotateBilinear(-angle) { FillColor = Color.Black };
                    blobImage = rotationFilter.Apply(blobImage);

                    // crop
                    blobImage = new ExtractBiggestBlob().Apply(blobImage);

                    new Invert().ApplyInPlace(blobImage);
                    yield return blobImage;
                }
            }
            else
            {
                yield return bitmap;
            }
        }
Example #12
0
        private WriteableBitmap FindPlate(IEnumerable<Rect> rects, WriteableBitmap image)
        {
            WriteableBitmap bestCandidate = null;
            
            foreach (var rect in rects)
            {
                var croppedImage = image.Crop(rect);
                var edgeFilter = new CannyEdgeDetector();
                var smoothFilter = new Median();
                var grayFilter = new Grayscale(0.2125, 0.7154, 0.0721);
                var blobCounter = new BlobCounter();
                var cutTop = croppedImage.PixelHeight * 0.3;

                croppedImage = croppedImage.Crop(new Rect(0, cutTop, croppedImage.PixelWidth, croppedImage.PixelHeight));

                var bitmap = (Bitmap)croppedImage;
                var grayImage = grayFilter.Apply(bitmap);

                bitmap = smoothFilter.Apply(grayImage);
                edgeFilter.ApplyInPlace(bitmap);
                blobCounter.ProcessImage(bitmap);

                var blobs = blobCounter.GetObjectsInformation();
                var possibleChars = new List<Rectangle>();

                foreach (var blob in blobs)
                {
                    var objRectangle = blob.Rectangle;
                    var ratio = (double)objRectangle.Height / (double)objRectangle.Width;
                    
                    if (ratio >= 1.16d && ratio <= 6.3d)
                    {
                        possibleChars.Add(objRectangle);
                    }
                }

                if (possibleChars.Count == 0)
                {
                    continue;
                }

                bestCandidate = croppedImage;
            }

            return bestCandidate;
        }
        private static Blob[] blobRecognition(Bitmap thresholdedInverted)
        {
            //Use the AForge.NET BlobCounter to perform Blob Recognition / Connected Region Analysis
            BlobCounter blobRecognition = new BlobCounter();

            //Filter out blobs that are abviously the wrong size to be characters
            blobRecognition.MinWidth = (int)(thresholdedInverted.Width * (BLOB_FILTER_MIN_DIMENSION_IMAGE_PERCENTAGE / 100));
            blobRecognition.MinHeight = (int)(thresholdedInverted.Height * (BLOB_FILTER_MIN_DIMENSION_IMAGE_PERCENTAGE / 100));
            blobRecognition.MaxWidth = (int)(thresholdedInverted.Width * (BLOB_FILTER_MAX_DIMENSION_IMAGE_PERCENTAGE / 100));
            blobRecognition.MaxHeight = (int)(thresholdedInverted.Height * (BLOB_FILTER_MAX_DIMENSION_IMAGE_PERCENTAGE / 100));
            blobRecognition.FilterBlobs = true;

            blobRecognition.ProcessImage(thresholdedInverted);
            Blob[] blobs = blobRecognition.GetObjectsInformation();

            return blobs;
        }
Example #14
0
        public List<Blob> ExtractBlob()
        {
            // create instance of blob counter
            BlobCounter blobCounter = new BlobCounter();
            // process input image
            blobCounter.ProcessImage(ImageBitmap);
            
            // get information about detected objects   
            
            Blob[] blobArray = blobCounter.GetObjectsInformation();

            foreach(Blob blobdata in blobArray)
            {
                blobCounter.ExtractBlobsImage(ImageBitmap, blobdata, true);
            }
            
            return blobArray.ToList();
        }
        Blob[] DetectBlobs(Bitmap bmp)
        {
            Invert filter = new Invert();
            filter.ApplyInPlace(bmp);

            BlobCounter bc = new BlobCounter();
            bc.BackgroundThreshold = Color.FromArgb(8, 8, 8);

            bc.BlobsFilter = new BlobsFilter(bmp.Size);
            bc.FilterBlobs = true;

            bc.ProcessImage(bmp);

            // Revert back
            filter.ApplyInPlace(bmp);

            return bc.GetObjectsInformation();
        }
        // Process specified image trying to recognize counter's image
        public void Process(Bitmap image, IImageProcessingLog log)
        {
            log.AddMessage("Image size: " + image.Width +
                 " x " + image.Height);

            //get image
            byte[] textData = GetImageData();
            UnmanagedImage img = CreateImage(textData);
            log.AddImage("Raw Image", img.ToManagedImage());

            //resize Image
            AForge.Imaging.Filters.ResizeNearestNeighbor resizeFilter = new AForge.Imaging.Filters.ResizeNearestNeighbor(500, (int)(500 / res));
            UnmanagedImage resizedImage = resizeFilter.Apply(img);
            log.AddImage("Resized Image", resizedImage.ToManagedImage());
            
            //filter floor
            UnmanagedImage floorFilteredImage = FilterFloor(resizedImage, textData);
            log.AddImage("Floor filtered", floorFilteredImage.ToManagedImage());

            // 1- grayscale image
            Bitmap grayImage =
                 Grayscale.CommonAlgorithms.BT709.Apply(resizedImage.ToManagedImage());
            log.AddImage("Grayscale", resizedImage.ToManagedImage());

            // 2 - Otsu thresholding
            OtsuThreshold threshold = new OtsuThreshold();
            Bitmap binaryImage = threshold.Apply(grayImage);
            log.AddImage("Binary", binaryImage);
            log.AddMessage("Otsu threshold: " + threshold.ThresholdValue);
            //resive image

            // 3 - Blob counting
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinWidth = 1;
            blobCounter.MinWidth = 1;

            blobCounter.ProcessImage(binaryImage);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            log.AddMessage("Found blobs (min width/height = 24): " +
                 blobs.Length);

        }
Example #17
0
        public Bitmap ProcessFrame(Bitmap inputBitmap, int x, int y)
        {
            // Create an image for AForge to process
            Bitmap workingImage = new Bitmap(inputBitmap.Width, inputBitmap.Height);
            workingImage = AForge.Imaging.Image.Clone(inputBitmap, PixelFormat.Format24bppRgb);

            // Create a mask for ROI selection
            Rectangle roi = new Rectangle(x - 30, y-30, 80, 80);

            Crop roicrop = new Crop(roi);
            Bitmap outimage = roicrop.Apply(workingImage);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.ObjectsOrder = ObjectsOrder.Area;

            Blob[] blobs;

            // Find the blobs
            blobCounter.ProcessImage(outimage);
            blobs = blobCounter.GetObjectsInformation();
            List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[0]);

            GrahamConvexHull grahamScan = new GrahamConvexHull();
            List<IntPoint> hullPoints = grahamScan.FindHull(edgePoints);

            Graphics g = Graphics.FromImage(outimage);
            Pen redPen = new Pen(Color.Red, 2);

            g.DrawPolygon(redPen, ToPointsArray(hullPoints));

            //g.Clear(Color.Black);
            //g.DrawImage(handImage, x, y);
            //g.DrawRectangle(redPen, roi);
            //g.DrawEllipse(redPen, x, y, 20, 20);

            ResizeNearestNeighbor resizeFilter = new ResizeNearestNeighbor(160, 160);
            Bitmap resizedImage = resizeFilter.Apply(outimage);

            return resizedImage;
        }
Example #18
0
        public List<Blob> ExtractBlob(int maxWidth, int maxHeight, int minWidth, int minHeight)
        {
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.MinHeight = minHeight;
            blobCounter.MinWidth = minWidth;
            blobCounter.MaxWidth = maxWidth;
            blobCounter.MaxHeight = maxHeight;
            blobCounter.FilterBlobs = true;
            // process input image
            blobCounter.ProcessImage(ImageBitmap);

            // get information about detected objects   

            Blob[] blobArray = blobCounter.GetObjectsInformation();

            foreach (Blob blobdata in blobArray)
            {
                blobCounter.ExtractBlobsImage(ImageBitmap, blobdata, true);
            }

            return blobArray.ToList();
        }        
Example #19
0
        public static List<List<IntPoint>> Quadrilaterals(Bitmap img, int minWidth, int minHeight)
        {
            Bitmap thresholdedImg = FilterCombinations.AdaptiveThreshold(img);

            //Use blob recognition on the image to find all blobs meeting the specified minimum width & height
            BlobCounter blobCounter = new BlobCounter();

            //Filter out small blobs
            blobCounter.MinWidth = minWidth;
            blobCounter.MinHeight = minHeight;
            blobCounter.FilterBlobs = true;

            //Order the blobs by size (desc), as since we're looking for quads of a minimum size, it's likely we'll be more interested in the laregr ones
            blobCounter.ObjectsOrder = ObjectsOrder.Size;

            //Check if each blob is approximately a quadriateral, and if so store the 4 corners
            List<List<IntPoint>> foundQuads = new List<List<IntPoint>>();
            //Shape checker to be used to test if a blob is a quadrilateral
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            //Find the blobs
            blobCounter.ProcessImage(thresholdedImg);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            foreach(Blob b in blobs)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(b);
                List<IntPoint> corners = null;

                //Is this blob approximately a quadrilateral?
                if(shapeChecker.IsQuadrilateral(edgePoints, out corners))
                {
                    //Store the Quad's corners
                    foundQuads.Add(corners);
                }
            }

            return foundQuads;
        }
Example #20
0
        public static AForge.Point GetRedBlobCenter(Bitmap image)
        {
            BlobCounter bCounter = new BlobCounter();
            bCounter.ProcessImage(image);

            Blob[] blobs = bCounter.GetObjectsInformation();
            Rectangle[] rects = bCounter.GetObjectsRectangles();

            Pen pen = new Pen(Color.Red, 2);
            Brush brush = new SolidBrush(Color.Red);
            Graphics g = Graphics.FromImage(image);

            if (rects.Length > 0) { g.FillRectangle(brush, rects[0]); }

            if (blobs.Length > 0)
            {

                detected = true;
                lastPos = blobs[0].CenterOfGravity;

                AForge.Point rPos = new AForge.Point();
                rPos.Y = ((lastPos.Y / 5) / 100) * 768;
                rPos.X = ((lastPos.X / 5) / 100) * 1366;

                return rPos;
            }
            else
            {
                detected = false;
                if (lastPos != null)
                {
                    return lastPos;
                }
                else
                {
                    return new AForge.Point(50.0f, 50.0f);
                }
            }
        }
Example #21
0
        public Boolean ContainOrange(Bitmap bitmap)
        {
            ColorFiltering RedFilter = new ColorFiltering();

            RedFilter.Red   = new IntRange(100, 255);
            RedFilter.Green = new IntRange(0, 100);
            RedFilter.Blue  = new IntRange(0, 100);
            RedFilter.ApplyInPlace(bitmap);
            AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter();

            blobCounterGreen.FilterBlobs = true;
            blobCounterGreen.MinHeight   = 5;
            blobCounterGreen.MinWidth    = 5;
            blobCounterGreen.ProcessImage(bitmap);
            AForge.Imaging.Blob[] blobsGreen        = blobCounterGreen.GetObjectsInformation();
            SimpleShapeChecker    shapeCheckerGreen = new SimpleShapeChecker();

            if (blobsGreen.Length > 0)
            {
                return(true);
            }
            return(false);
        }
Example #22
0
        public String ContainRed(Bitmap bitmap)
        {
            HSLFiltering filterRed = new HSLFiltering();

            filterRed.Hue        = new IntRange(301, 9);   //red at night (334, 40)
            filterRed.Saturation = new Range(0.4f, 1);     //0.55
            filterRed.Luminance  = new Range(0.1f, 0.68f); //75
            filterRed.ApplyInPlace(bitmap);

            AForge.Imaging.BlobCounter blobCounterRed = new AForge.Imaging.BlobCounter();
            blobCounterRed.FilterBlobs  = true;
            blobCounterRed.ObjectsOrder = ObjectsOrder.Area;
            blobCounterRed.MinHeight    = 10;
            blobCounterRed.MinWidth     = 10;
            blobCounterRed.ProcessImage(bitmap);

            AForge.Imaging.Blob[] blobsRed = blobCounterRed.GetObjectsInformation();
            //capturedPhotoRed.Source = (WriteableBitmap)bitmap;
            //Mean filter = new Mean();
            //// apply the filter
            //filter.ApplyInPlace(bitmap);
            for (int iBlob = 0; iBlob < blobsRed.Length; iBlob++)
            {
                for (int jBlob = iBlob + 1; jBlob < blobsRed.Length; jBlob++)
                {
                    if ((Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) < blobsRed[iBlob].Rectangle.Width / 2) &&
                        (Math.Abs(blobsRed[iBlob].CenterOfGravity.Y - blobsRed[jBlob].CenterOfGravity.Y) < 3 * blobsRed[iBlob].Rectangle.Height) &&
                        (Math.Abs(blobsRed[iBlob].Area - blobsRed[jBlob].Area) < blobsRed[iBlob].Area / 2))
                    {
                        //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) + "w" + blobsRed[iBlob].Rectangle.Width / 2; }
                        //catch (Exception ex) { text_log.Text = ex + ""; }
                        return("red");
                    }
                }
            }
            return("");
        }
Example #23
0
        public String ContainPurple(Bitmap bitmap)
        {
            HSLFiltering filter = new HSLFiltering();

            // set color ranges to keep
            filter.Hue        = new IntRange(220, 290);
            filter.Saturation = new Range(0.4f, 0.8f);
            filter.Luminance  = new Range(0.35f, 0.78f);
            filter.ApplyInPlace(bitmap);

            AForge.Imaging.BlobCounter blobCounterPutple = new AForge.Imaging.BlobCounter();
            blobCounterPutple.FilterBlobs  = true;
            blobCounterPutple.ObjectsOrder = ObjectsOrder.Area;
            blobCounterPutple.MinHeight    = 10;
            blobCounterPutple.MinWidth     = 10;
            blobCounterPutple.ProcessImage(bitmap);
            AForge.Imaging.Blob[] blobsPurple        = blobCounterPutple.GetObjectsInformation();
            SimpleShapeChecker    shapeCheckerPurple = new SimpleShapeChecker();

            //capturedPhotoBlue.Source = (WriteableBitmap)bitmap;
            for (int iBlob = 0; iBlob < blobsPurple.Length; iBlob++)
            {
                for (int jBlob = iBlob + 1; jBlob < blobsPurple.Length; jBlob++)
                {
                    if ((Math.Abs(blobsPurple[iBlob].CenterOfGravity.X - blobsPurple[jBlob].CenterOfGravity.X) < blobsPurple[iBlob].Rectangle.Width / 2) &&
                        (Math.Abs(blobsPurple[iBlob].CenterOfGravity.Y - blobsPurple[jBlob].CenterOfGravity.Y) < 3 * blobsPurple[iBlob].Rectangle.Height) &&
                        (Math.Abs(blobsPurple[iBlob].Area - blobsPurple[jBlob].Area) < blobsPurple[iBlob].Area / 2))
                    {
                        //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsPurple[iBlob].CenterOfGravity.X - blobsPurple[jBlob].CenterOfGravity.X) + "w" + blobsPurple[iBlob].Rectangle.Width / 2; }
                        //catch (Exception ex) { text_log.Text = ex + ""; }
                        return("Purple");
                    }
                }
            }
            return("");
        }
Example #24
0
        // =========================================================
        private Bitmap DrawRectanglesFunct(Bitmap image)
        {
            // step 1 - turn background to black (done)

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 3;
            blobCounter.MinWidth = 3;
            blobCounter.ProcessImage(image);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // step 3 - check objects' type and do what you do:
            Graphics g = Graphics.FromImage(image);
            Pen pen = new Pen(Color.DarkOrange, 2);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                SimpleShapeChecker ShapeChecker = new SimpleShapeChecker();
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> cornerPoints;

                // fine tune ShapeChecker
                ShapeChecker.AngleError = 15;  // default 7
                ShapeChecker.LengthError = 0.3F;  // default 0.1 (10%)
                ShapeChecker.MinAcceptableDistortion = 0.9F;  // in pixels, default 0.5
                ShapeChecker.RelativeDistortionLimit = 0.2F;  // default 0.03 (3%)

                // use the Outline checker to extract the corner points
                if (ShapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
                {
                    // only do things if the corners form a rectangle
                    if (ShapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle)
                    {
                        List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
                        g.DrawPolygon(pen, ToPointsArray(corners));
                    }
                }
            }
            return (image);
        }
Example #25
0
        // ==========================================================================================================
        // Components:
        // ==========================================================================================================
        private List<Shapes.Component> FindComponentsFunct(Bitmap bitmap)
        {
            // Locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 8;
            blobCounter.MinWidth = 8;
            blobCounter.ProcessImage(bitmap);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // create convex hull searching algorithm
            GrahamConvexHull hullFinder = new GrahamConvexHull();
            ClosePointsMergingOptimizer optimizer1 = new ClosePointsMergingOptimizer();
            FlatAnglesOptimizer optimizer2 = new FlatAnglesOptimizer();

            List<Shapes.Component> Components = new List<Shapes.Component>();

            // process each blob
            foreach (Blob blob in blobs)
            {
                List<IntPoint> leftPoints, rightPoints, edgePoints = new List<IntPoint>();
                if ((blob.Rectangle.Height > 400) && (blob.Rectangle.Width > 600))
                {
                    break;	// The whole image could be a blob, discard that
                }
                // get blob's edge points
                blobCounter.GetBlobsLeftAndRightEdges(blob,
                    out leftPoints, out rightPoints);

                edgePoints.AddRange(leftPoints);
                edgePoints.AddRange(rightPoints);

                // blob's convex hull
                List<IntPoint> Outline = hullFinder.FindHull(edgePoints);
                optimizer1.MaxDistanceToMerge = 4;
                optimizer2.MaxAngleToKeep = 170F;
                Outline = optimizer2.OptimizeShape(Outline);
                Outline = optimizer1.OptimizeShape(Outline);

                // find Longest line segment
                float dist = 0;
                LineSegment Longest = new LineSegment(Outline[0], Outline[1]);
                LineSegment line;
                dist = Longest.Length;
                int LongestInd = 0;
                for (int i = 1; i < Outline.Count; i++)
                {
                    if (i != Outline.Count - 1)
                    {
                        line = new LineSegment(Outline[i], Outline[i + 1]);
                    }
                    else
                    {
                        // last iteration
                        if (Outline[i] == Outline[0])
                        {
                            break;
                        }
                        line = new LineSegment(Outline[i], Outline[0]);
                    }
                    if (line.Length > dist)
                    {
                        Longest = line;
                        dist = line.Length;
                        LongestInd = i;
                    }
                }
                // Get the center point of it
                AForge.Point LongestCenter = new AForge.Point();
                LongestCenter.X = (float)Math.Round((Longest.End.X - Longest.Start.X) / 2.0 + Longest.Start.X);
                LongestCenter.Y = (float)Math.Round((Longest.End.Y - Longest.Start.Y) / 2.0 + Longest.Start.Y);
                AForge.Point NormalStart = new AForge.Point();
                AForge.Point NormalEnd = new AForge.Point();
                // Find normal:
                // start= longest.start rotated +90deg relative to center
                // end= longest.end rotated -90deg and relative to center
                // If you rotate point (px, py) around point (ox, oy) by angle theta you'll get:
                // p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox
                // p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy
                // cos90 = 0, sin90= 1 =>
                // p'x= -(py-oy) + ox= oy-py+ox, p'y= (px-ox)+ oy
                NormalStart.X = LongestCenter.Y - Longest.Start.Y + LongestCenter.X;
                NormalStart.Y = (Longest.Start.X - LongestCenter.X) + LongestCenter.Y;
                // cos-90=0, sin-90= -1 =>
                // p'x= (py-oy) + ox
                // p'y= -(px-ox)+oy= ox-px+oy
                NormalEnd.X = (Longest.Start.Y - LongestCenter.Y) + LongestCenter.X;
                NormalEnd.Y = LongestCenter.X - Longest.Start.X + LongestCenter.Y;
                // Make line out of the points
                Line Normal = Line.FromPoints(NormalStart, NormalEnd);

                // Find the furthest intersection to the normal (skip the Longest)
                AForge.Point InterSection = new AForge.Point();
                AForge.Point Furthest = new AForge.Point();
                bool FurhtestAssinged = false;
                LineSegment seg;
                dist = 0;
                for (int i = 0; i < Outline.Count; i++)
                {
                    if (i == LongestInd)
                    {
                        continue;
                    }
                    if (i != Outline.Count - 1)
                    {
                        seg = new LineSegment(Outline[i], Outline[i + 1]);
                    }
                    else
                    {
                        // last iteration
                        if (Outline[i] == Outline[0])
                        {
                            break;
                        }
                        seg = new LineSegment(Outline[i], Outline[0]);
                    }
                    if (seg.GetIntersectionWith(Normal) == null)
                    {
                        continue;
                    }
                    InterSection = (AForge.Point)seg.GetIntersectionWith(Normal);
                    if (InterSection.DistanceTo(LongestCenter) > dist)
                    {
                        Furthest = InterSection;
                        FurhtestAssinged = true;
                        dist = InterSection.DistanceTo(LongestCenter);
                    }
                }
                // Check, if there is a edge point that is close to the normal even further
                AForge.Point fPoint = new AForge.Point();
                for (int i = 0; i < Outline.Count; i++)
                {
                    fPoint.X = Outline[i].X;
                    fPoint.Y = Outline[i].Y;
                    if (Normal.DistanceToPoint(fPoint) < 1.5)
                    {
                        if (fPoint.DistanceTo(LongestCenter) > dist)
                        {
                            Furthest = fPoint;
                            FurhtestAssinged = true;
                            dist = fPoint.DistanceTo(LongestCenter);
                        }
                    }
                }
                AForge.Point ComponentCenter = new AForge.Point();
                if (FurhtestAssinged)
                {
                    // Find the midpoint of LongestCenter and Furthest: This is the centerpoint of component
                    ComponentCenter.X = (float)Math.Round((LongestCenter.X - Furthest.X) / 2.0 + Furthest.X);
                    ComponentCenter.Y = (float)Math.Round((LongestCenter.Y - Furthest.Y) / 2.0 + Furthest.Y);
                    // Alignment is the angle of longest
                    double Alignment;
                    if (Math.Abs(Longest.End.X - Longest.Start.X) < 0.001)
                    {
                        Alignment = 0;
                    }
                    else
                    {
                        Alignment = Math.Atan((Longest.End.Y - Longest.Start.Y) / (Longest.End.X - Longest.Start.X));
                        Alignment = Alignment * 180.0 / Math.PI; // in deg.
                    }
                    Components.Add(new Shapes.Component(ComponentCenter, Alignment, Outline, Longest, NormalStart, NormalEnd));
                }
            }
            return Components;
        }
Example #26
0
        // ==========================================================================================================
        // Circles:
        // ==========================================================================================================
        private List<Shapes.Circle> FindCirclesFunct(Bitmap bitmap)
        {
            // locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 5;
            blobCounter.MinWidth = 5;
            blobCounter.ProcessImage(bitmap);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            List<Shapes.Circle> Circles = new List<Shapes.Circle>();

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                AForge.Point center;
                float radius;

                // is circle ?
                if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    if (radius > 3)  // MirrFilter out some noise
                    {
                        Circles.Add(new Shapes.Circle(center.X, center.Y, radius));
                    }
                }
            }
            return (Circles);
        }
Example #27
0
        private void FindCenterMarker()
        {
            List<Marker> _blobs = new List<Marker>();
            //блокируем изображение в памяти
            BitmapData bitmapData = _markersimg.LockBits(
                new Rectangle(0, 0, _markersimg.Width, _markersimg.Height),
                ImageLockMode.ReadWrite, _markersimg.PixelFormat);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            //устанавливаем фильтр и максимальные и минимальные размеры маркера
            blobCounter.MinHeight = blobCounter.MinWidth = Geometry.MMtoPX(_makerdiameter - 2.0d, _image.VerticalResolution);
            blobCounter.MaxHeight = blobCounter.MaxWidth = Geometry.MMtoPX(_makerdiameter + 3.0d, _image.VerticalResolution);

            //собственно поиск
            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            _markersimg.UnlockBits(bitmapData);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {

                if (blobs[i].Fullness > 0.3)
                {

                    Marker tempmark = new Marker(blobs[i]);
                    _blobs.Add(tempmark);

                }
            }
            this.RecognizeMarkers(_blobs);
        }
Example #28
0
        /// <summary>
        /// Scans dominant color on image and returns it.
        /// Crops rank part on image and analyzes suit part on image
        /// </summary>
        /// <param name="bmp">Bitmap to be scanned</param>
        /// <returns>Returns 'B' for black , 'R' for red</returns>
        private char ScanColor(Bitmap bmp)
        {
            //System.Diagnostics.Debug.Flush();
            //System.Diagnostics.Debug.Print("I'm here");
            char color = 'B';
            //Crop rank part


            Crop crop = new Crop(new Rectangle(0, bmp.Height / 2, bmp.Width, bmp.Height / 2));
            bmp = crop.Apply(bmp);
            Bitmap temp = commonSeq.Apply(bmp); //Apply filters

            //Find suit blob on image
            BlobCounter counter = new BlobCounter();
            counter.ProcessImage(temp);
            Blob[] blobs = counter.GetObjectsInformation();

            if (blobs.Length > 0) //If blobs found
            {
                Blob max = blobs[0];
                //Find blob whose size is biggest 
                foreach (Blob blob in blobs)
                {
                    if (blob.Rectangle.Height > max.Rectangle.Height)
                        max = blob;
                    else if (blob.Rectangle.Height == max.Rectangle.Height)
                        max = blob.Rectangle.Width > max.Rectangle.Width ? blob : max;
                }
                QuadrilateralTransformation trans = new QuadrilateralTransformation();
                trans.SourceQuadrilateral = PointsCloud.FindQuadrilateralCorners(counter.GetBlobsEdgePoints(max));
                bmp = trans.Apply(bmp); //Extract suit
            }
            //Lock Bits for processing

            //int bitsPerPixel = ((int)bmp.PixelFormat & 0xff00) >> 8;
            //int bytesPerPixel = (bitsPerPixel + 7) / 8;
            //int stride = 4 * ((bmp.Width * bytesPerPixel + 3) / 4);


           // BitmapData imageData=new BitmapData(bmp.Width, bmp.Height, bmp. )
          // BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),ImageLockMode.ReadOnly, bmp.PixelFormat);
            int totalRed = 0;
            int totalBlack = 0;

            WriteableBitmap wbmp = (WriteableBitmap)bmp;

            wbmp.ForEach((x, y, pcolor) =>
            {
                int r=Convert.ToInt32(pcolor.R);
                int g=Convert.ToInt32(pcolor.G);
                int b=Convert.ToInt32(pcolor.B);

                if (r > g + b)
                    totalRed++;
                else if (r <= g + b && (r < 50 && g < 50))
                    totalBlack++;

                return pcolor;

            });

            

            if (totalRed > totalBlack) //If red is dominant
                color = 'R'; //Set color as Red

            return color;
        }
        /// <summary>
        /// Detects and recognizes cards from source image
        /// </summary>
        /// <param name="source">Source image to be scanned</param>
        /// <returns>Recognized Cards</returns>
        public CardCollection Recognize(Bitmap source)
        {
            CardCollection collection = new CardCollection();  //Collection that will hold cards
            Bitmap temp = source.Clone() as Bitmap; //Clone image to keep original image

            FiltersSequence seq = new FiltersSequence();
            seq.Add(Grayscale.CommonAlgorithms.BT709);  //First add  grayScaling filter
            seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter
            temp = seq.Apply(source); // Apply filters on source image

            //Extract blobs from image whose size width and height larger than 150
            BlobCounter extractor = new BlobCounter();
            extractor.FilterBlobs = true;
            extractor.MinWidth = extractor.MinHeight = 150;
            extractor.MaxWidth = extractor.MaxHeight = 350;
            extractor.ProcessImage(temp);

            //Will be used transform(extract) cards on source image
            QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation();

            //Will be used resize(scaling) cards
            ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight);

            foreach (Blob blob in extractor.GetObjectsInformation())
            {
                //Get Edge points of card
                List<IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob);
                //Calculate/Find corners of card on source image from edge points
                List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);

                quadTransformer.SourceQuadrilateral = corners; //Set corners for transforming card
                quadTransformer.AutomaticSizeCalculaton = true;

                Bitmap cardImg = quadTransformer.Apply(source); //Extract(transform) card image

                if (cardImg.Width > cardImg.Height) //If card is positioned horizontally
                    cardImg.RotateFlip(RotateFlipType.Rotate90FlipNone); //Rotate
                cardImg = resizer.Apply(cardImg); //Normalize card size

                Card card = new Card(cardImg, corners.ToArray()); //Create Card Object
                bool faceCard = IsFaceCard(cardImg); //Determine type of card(face or not)

                ResizeBicubic res;

                seq.Clear();
                seq.Add(Grayscale.CommonAlgorithms.BT709);
                seq.Add(new OtsuThreshold());

                Bitmap topLeftSuit = card.GetTopLeftSuitPart();
                Bitmap bmp = seq.Apply(topLeftSuit);

                bmp = CutWhiteSpaces(bmp);
                res = new ResizeBicubic(32, 40);
                bmp = res.Apply(bmp);

                Bitmap topLeftRank = card.GetTopLeftRankPart();
                Bitmap bmp2 = seq.Apply(topLeftRank);

                bmp2 = CutWhiteSpaces(bmp2);

                seq.Clear();
                seq.Add(new OtsuThreshold());
                bmp = seq.Apply(bmp);
                card.Suit = ScanSuit(bmp);

                if (!faceCard)
                {
                    res = new ResizeBicubic(26, 40);
                    bmp2 = res.Apply(bmp2);
                    seq.Clear();
                    seq.Add(new OtsuThreshold());
                    bmp2 = seq.Apply(bmp2);
                    card.Rank = ScanRank(bmp2);
                }
                else
                {
                    res = new ResizeBicubic(32, 40);
                    bmp2 = res.Apply(bmp2);
                    seq.Clear();
                    seq.Add(new OtsuThreshold());
                    bmp2 = seq.Apply(bmp2);
                    card.Rank = ScanFaceRank(bmp2);
                }
                collection.Add(card); //Add card to collection
            }
            return collection;
        }
Example #30
0
        /// <summary>
        /// Добавляет несколько несколько ячеек в ответ начиная с первой
        /// </summary>
        /// <param name="image">Ссылка ни изображение</param>
        /// <param name="CellsCount">Количество ячеек для добавления в ответ</param>
        /// <param name="FirstCellDistanses">Коллекция дистанций между первой ячейкой и маркерами</param>
        /// <param name="intercentresdistX">Расстояние между центрами ячеек</param>
        /// <param name="Width">Длина ячеек</param>
        /// <param name="Height">Высота ячеек</param>
        public void IntelligentAdd(Bitmap image, int CellsCount, Distances FirstCellDistanses, int intercentresdistX, int Width, int Height)
        {
            int maxslice = intercentresdistX/2;

            //находим первую доступную дистанцию
            Distance d = FirstCellDistanses.FindOneGood();
            int maxWidth = Width +  Convert.ToInt16(Width/2);
            int maxHeigth = Height + Convert.ToInt16(Height/2);
            //увеличиваем ячейки

            this.Add(image,CellsCount,FirstCellDistanses,intercentresdistX,maxWidth,maxHeigth);

            BitmapData data = image.LockBits(_cells[0].Rect, ImageLockMode.ReadWrite, image.PixelFormat);
            BlobCounter blobCounter = new BlobCounter();

            Invert invertfilter = new Invert();
            invertfilter.ApplyInPlace(data);
            blobCounter.ProcessImage(data);

            Blob[] blobs = blobCounter.GetObjectsInformation();
            if (blobs.Length != 0)
            {
                int maxar = 0;
                int b = 0;
                for (int i = 0; i < blobs.Count(); i++)
                {
                    if (blobs[i].Area > maxar) { maxar = blobs[i].Area; b = i; }
                }
                invertfilter.ApplyInPlace(data);

                System.Drawing.Point p = new System.Drawing.Point(_cells[0].CenterOfGravity.X - ((maxWidth / 2) - Convert.ToInt16(blobs[b].CenterOfGravity.X)), _cells[0].CenterOfGravity.Y - ((maxHeigth / 2) - Convert.ToInt16(blobs[b].CenterOfGravity.Y)));
                if (Math.Abs(_cells[0].CenterOfGravity.Y - p.Y) <= maxslice) { this.ReMeasure(p, intercentresdistX, Width, Height); }
                else { this.ReMeasure(_cells[0].CenterOfGravity, intercentresdistX, Width, Height); }
            }
            image.UnlockBits(data);
        }
        /// <summary>
        /// Scans dominant color on image and returns it.
        /// Crops rank part on image and analyzes suit part on image
        /// </summary>
        /// <param name="bmp">Bitmap to be scanned</param>
        /// <returns>Returns 'B' for black , 'R' for red</returns>
        private char ScanColor(Bitmap bmp)
        {
            char color = 'B';
            //Crop rank part
            Crop crop = new Crop(new Rectangle(0, bmp.Height / 2, bmp.Width, bmp.Height / 2));
            bmp = crop.Apply(bmp);
            Bitmap temp = commonSeq.Apply(bmp); //Apply filters

            //Find suit blob on image
            BlobCounter counter = new BlobCounter();
            counter.ProcessImage(temp);
            Blob[] blobs = counter.GetObjectsInformation();

            if (blobs.Length > 0) //If blobs found
            {
                Blob max = blobs[0]; 
                //Find blob whose size is biggest 
                foreach (Blob blob in blobs)
                {
                    if (blob.Rectangle.Height > max.Rectangle.Height)
                        max = blob;
                    else if (blob.Rectangle.Height == max.Rectangle.Height)
                        max = blob.Rectangle.Width > max.Rectangle.Width ? blob : max;
                }
                QuadrilateralTransformation trans = new QuadrilateralTransformation();
                trans.SourceQuadrilateral = PointsCloud.FindQuadrilateralCorners(counter.GetBlobsEdgePoints(max));
                bmp = trans.Apply(bmp); //Extract suit
            }
            //Lock Bits for processing
            BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
               ImageLockMode.ReadOnly, bmp.PixelFormat);
            int totalRed = 0;
            int totalBlack = 0;

            unsafe
            {
                //Count red and black pixels
                try
                {
                    UnmanagedImage img = new UnmanagedImage(imageData);
     
                    int height = img.Height;
                    int width = img.Width;
                    int pixelSize = (img.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
                    byte* p = (byte*)img.ImageData.ToPointer();

                    // for each line
                    for (int y = 0; y < height; y++)
                    {
                        // for each pixel
                        for (int x = 0; x < width; x++, p += pixelSize)
                        {
                            int r = (int)p[RGB.R]; //Red pixel value
                            int g = (int)p[RGB.G]; //Green pixel value
                            int b = (int)p[RGB.B]; //Blue pixel value

                            if (r > g + b) //If red component is bigger then total of green and blue component
                                totalRed++;  //then its red

                            if (r <= g + b && r < 50 && g < 50 && b < 50) //If all components less 50
                                totalBlack++; //then its black
                        }
                    }

                }
                finally
                {
                    bmp.UnlockBits(imageData); //Unlock
                }
            }
            if (totalRed > totalBlack) //If red is dominant
                color = 'R'; //Set color as Red

            return color;
        }
        /// <summary>
        /// Scans rank of card and returns result.
        /// For recognizing rank, counts suits on image 
        /// </summary>
        /// <param name="cardImage">Card image to be scanned</param>
        /// <returns>Rank of card</returns>
        private Rank ScanRank(Bitmap cardImage)
        {
            Rank rank = Rank.NOT_RECOGNIZED;

            int total = 0;
            Bitmap temp = commonSeq.Apply(cardImage); //Apply filters on image

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            //Filter blobs whose width or height less than 30 pixels
            blobCounter.MinHeight = blobCounter.MinWidth = 30; 
            blobCounter.ProcessImage(temp);

            total = blobCounter.GetObjectsInformation().Length; //Get total number of objects

            rank = (Rank)total; //Convert it to Rank

            return rank;
        }
Example #33
0
        /// <summary>
        /// Detects and recognizes cards from source image
        /// </summary>
        /// <param name="source">Source image to be scanned</param>
        /// <returns>Recognized Cards</returns>
        public List<Card> Recognize(Bitmap source)
        {
            List<Card> collection = new List<Card>();
            
            Bitmap temp = source.Clone(source.PixelFormat) as Bitmap; //Clone image to keep original image

            FiltersSequence seq = new FiltersSequence();
            seq.Add(Grayscale.CommonAlgorithms.BT709);  //First add  grayScaling filter
            seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter
            temp = seq.Apply(source); // Apply filters on source image

            //Extract blobs from image whose size width and height larger than 150
            BlobCounter extractor = new BlobCounter();
            extractor.FilterBlobs = true;
            extractor.MinWidth = extractor.MinHeight = 150;
            extractor.MaxWidth = extractor.MaxHeight = 350;
            extractor.ProcessImage(temp);

            //Will be used transform(extract) cards on source image 
            QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation();

            //Will be used resize(scaling) cards 
            ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight);

            foreach (Blob blob in extractor.GetObjectsInformation())
            {
                //Get Edge points of card
                List<IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob);
                //Calculate/Find corners of card on source image from edge points
                List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);

                quadTransformer.SourceQuadrilateral = corners; //Set corners for transforming card 
                quadTransformer.AutomaticSizeCalculaton = true;

                Bitmap cardImg = quadTransformer.Apply(source); //Extract(transform) card image

                if (cardImg.Width > cardImg.Height) //If card is positioned horizontally
                {
                    WriteableBitmap wbmp=(WriteableBitmap)cardImg;
                    wbmp = wbmp.Rotate(90);
                    cardImg = (Bitmap)wbmp; //Rotate
                }
                cardImg = resizer.Apply(cardImg); //Normalize card size

                Card card = new Card(cardImg, corners.ToArray()); //Create Card Object
                char color = ScanColor(card.GetTopLeftPart()); //Scan color
                bool faceCard = IsFaceCard(cardImg); //Determine type of card(face or not)

                if (!faceCard)
                {
                    card.Suit = ScanSuit(cardImg, color); //Scan Suit of non-face card
                    card.Rank = ScanRank(cardImg); //Scan Rank of non-face card
                }
                else
                {
                    Bitmap topLeft = card.GetTopLeftPart();

                    seq = null;
                    seq = new FiltersSequence();

                    seq.Add(Grayscale.CommonAlgorithms.BT709);
                    seq.Add(new BradleyLocalThresholding());
                    topLeft = seq.Apply(topLeft);
                    BlobsFiltering bFilter = new BlobsFiltering(5, 5, 150, 150);
                    bFilter.ApplyInPlace(topLeft); //Filter blobs that can not be a suit

                    //topLeft.Save("topleft.bmp", ImageFormat.Bmp);

                    card.Suit = ScanFaceSuit(topLeft, color); //Scan suit of face card
                    card.Rank = ScanFaceRank(topLeft); //Scan rank of face card
                }
                collection.Add(card); //Add card to collection
            }
            return collection;
        }
Example #34
0
        /// <summary>
        /// Display little noise object on image
        /// </summary>
        /// <param name="fillColor">Color to fill noise bject</param>
        /// <param name="threshold">Threshold for noise oblect area</param>
        public Image DisplayNoise(Color fillColor, int threshold = 100)
        {
            Bitmap bitmapImage = new Bitmap(_digit);

            BlobCounter bc = new BlobCounter(bitmapImage);
            // specify sort order
            bc.ObjectsOrder = ObjectsOrder.Size;
            Blob[] blobs = bc.GetObjectsInformation();

            SolidBrush redBrush = new SolidBrush(fillColor);
            using (Graphics digit1Graph = Graphics.FromImage(bitmapImage))
            {
                foreach (Blob blob in blobs)
                {
                    if (blob.Area < threshold)
                        digit1Graph.FillRectangle(redBrush, blob.Rectangle);
                }
            }

            return bitmapImage;
        }
Example #35
0
        private async Task<IList<Rect>> GetPlateRectanglesAsync(Bitmap image)
        {
            var rectanglePoints = await Task.Factory.StartNew(() =>
            {
                var blobCounter = new BlobCounter
                {
                    FilterBlobs = true,
                    MinHeight = 5,
                    MinWidth = 5
                };

                blobCounter.ProcessImage(image);

                var blobs = blobCounter.GetObjectsInformation();
                var shapeChecker = new SimpleShapeChecker();
                var rectPoints = new List<List<AForgePoint>>();

                foreach (var blob in blobs)
                {
                    List<IntPoint> cornerPoints;
                    var edgePoints = blobCounter.GetBlobsEdgePoints(blob);
                    var points = new List<AForgePoint>();

                    if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
                    {
                        var polygonType = shapeChecker.CheckPolygonSubType(cornerPoints);

                        if (polygonType == PolygonSubType.Rectangle ||
                            polygonType == PolygonSubType.Parallelogram)
                        {
                            foreach (var point in cornerPoints)
                            {
                                points.Add(new AForgePoint(point.X, point.Y));
                            }

                            rectPoints.Add(points);
                        }
                    }
                }

                return rectPoints;
            });

            var rects = rectanglePoints.Select(points => GetRect(points)).ToList();
            var images = new List<WriteableBitmap>();
            var cadidatesRects = new List<Rect>();

            foreach (var rect in rects)
            {
                var ratio = rect.Height / rect.Width;

                if (ratio >= MinPlateRatio && ratio <= MaxPlateRatio)
                {
                    cadidatesRects.Add(rect);
                }
            }

            return cadidatesRects;
        }
Example #36
0
        /// <summary>
        /// Remove little noise object on binary image
        /// </summary>
        /// <param name="threshold">Threshold for noise oblect area</param>
        public void RemoveNoise(int threshold = 100)
        {
            BlobCounter bc = new BlobCounter(new Bitmap(_digit));
            // specify sort order
            bc.ObjectsOrder = ObjectsOrder.Size;
            Blob[] blobs = bc.GetObjectsInformation();

            SolidBrush redBrush = new SolidBrush(Color.Black);
            Bitmap tempBitmap = new Bitmap(_digit);
            using (Graphics digitGraph = Graphics.FromImage(tempBitmap))
            {
                foreach (Blob blob in blobs)
                {
                    if (blob.Area < threshold)
                        digitGraph.FillRectangle(redBrush, blob.Rectangle);
                }
            }

            _digit = tempBitmap;
        }
Example #37
0
        public static IEnumerable<MagicCard> DetectCardArt(Bitmap cameraBitmap)
        {
            var ret = new List<MagicCard>();

            var filteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(cameraBitmap);

            // edge filter
            var edgeFilter = new SobelEdgeDetector();
            edgeFilter.ApplyInPlace(filteredBitmap);

            // Threshhold filter
            var threshholdFilter = new Threshold(190);
            threshholdFilter.ApplyInPlace(filteredBitmap);

            var bitmapData = filteredBitmap.LockBits(
                new Rectangle(0, 0, filteredBitmap.Width, filteredBitmap.Height),
                ImageLockMode.ReadWrite, filteredBitmap.PixelFormat);

            var blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 125;
            blobCounter.MinWidth = 125;

            blobCounter.ProcessImage(bitmapData);
            var blobs = blobCounter.GetObjectsInformation();
            filteredBitmap.UnlockBits(bitmapData);

            var shapeChecker = new SimpleShapeChecker();
            var bm = new Bitmap(filteredBitmap.Width, filteredBitmap.Height, PixelFormat.Format24bppRgb);

            var cardPositions = new List<IntPoint>();
            foreach (var blob in blobs)
            {
                var edgePoints = blobCounter.GetBlobsEdgePoints(blob);

                List<IntPoint> corners;

                // only operate on 4 sided polygons
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    var subtype = shapeChecker.CheckPolygonSubType(corners);

                    if (corners.Count() != 4)
                        continue;

                    if (subtype != PolygonSubType.Parallelogram && subtype != PolygonSubType.Rectangle)
                        continue;

                    // if the image is sideways, rotate it so it'll match the DB card art
                    corners = Utilities.RotateCorners(corners).ToList();

                    if (Utilities.GetArea(corners) < 20000)
                        continue;

                    ret.Add( new MagicCard(cameraBitmap, corners));
                }
            }

            return ret;
        }
Example #38
0
        public bool markKnownForms()
        {
            if (currentImage != null)
            {
                try
                {
                    Bitmap image = new Bitmap(this.currentImage);
                    // lock image
                    BitmapData bmData = image.LockBits(
                        new Rectangle(0, 0, image.Width, image.Height),
                        ImageLockMode.ReadWrite, image.PixelFormat);

                    // turn background to black
                    ColorFiltering cFilter = new ColorFiltering();
                    cFilter.Red = new IntRange(0, 64);
                    cFilter.Green = new IntRange(0, 64);
                    cFilter.Blue = new IntRange(0, 64);
                    cFilter.FillOutsideRange = false;
                    cFilter.ApplyInPlace(bmData);

                    // locate objects
                    BlobCounter bCounter = new BlobCounter();

                    bCounter.FilterBlobs = true;
                    bCounter.MinHeight = 5;
                    bCounter.MinWidth = 5;

                    bCounter.ProcessImage(bmData);

                    numberOfShellsDetected = bCounter.ObjectsCount;

                    Blob[] baBlobs = bCounter.GetObjectsInformation();
                    image.UnlockBits(bmData);

                    // coloring objects
                    SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

                    Graphics g = Graphics.FromImage(image);
                    Pen yellowPen = new Pen(Color.Yellow, 2); // circles
                    Pen redPen = new Pen(Color.Red, 2);       // quadrilateral
                    Pen brownPen = new Pen(Color.Brown, 2);   // quadrilateral with known sub-type
                    Pen greenPen = new Pen(Color.Green, 2);   // known triangle
                    Pen bluePen = new Pen(Color.Blue, 2);     // triangle

                    for (int i = 0, n = baBlobs.Length; i < n; i++)
                    {
                        List<IntPoint> edgePoints = bCounter.GetBlobsEdgePoints(baBlobs[i]);
                        foreach (IntPoint point in edgePoints)
                            g.DrawEllipse(redPen, point.X, point.Y, 2, 2);

                        /*AForge.Point center;
                        float radius;

                        // is circle ?
                        if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                        {
                            numberOfShellsDetected++;
                            g.DrawEllipse(redPen,
                                (float)(center.X - radius), (float)(center.Y - radius),
                                (float)(radius * 2), (float)(radius * 2));
                        }*/
                        /*else
                        {
                            List<IntPoint> corners;

                            // is triangle or quadrilateral
                            if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                            {
                                PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
                                Pen pen;
                                if (subType == PolygonSubType.Unknown)
                                {
                                    pen = (corners.Count == 4) ? redPen : bluePen;
                                }
                                else
                                {
                                    pen = (corners.Count == 4) ? brownPen : greenPen;
                                }

                                g.DrawPolygon(pen, ToPointsArray(corners));
                            }
                        }*/
                    }
                    yellowPen.Dispose();
                    redPen.Dispose();
                    greenPen.Dispose();
                    bluePen.Dispose();
                    brownPen.Dispose();
                    g.Dispose();
                    this.currentImage = image;
                    return true;
                }
                catch (Exception e)
                {

                }
            }
            return false;
        }
Example #39
0
        /// <summary>
        /// Detect hand on a given frame
        /// </summary>
        /// <param name="image">Image to detect the hand palm within</param>
        /// <param name="cycles">Number of snapshot cycles to check against</param>
        /// <param name="similarityRate">The threshold percent of pixels that have to match for a positive result</param>
        /// <param name="trainingPic">A reference to secondary frame field. Temporary.</param>
        /// <returns>IntPoint point at the centre of detected hand palm</returns>
        public IntPoint DetectHand(Bitmap image, int cycles, int similarityRate, PictureBox trainingPic)
        {
            IntPoint dimensions = new IntPoint(image.Width, image.Height);
            BlobCounterBase bc = new BlobCounter();
            Crop cropFilter;

            bc.FilterBlobs = true;
            bc.MinWidth = (int)(avgSize.x * 0.6);
            bc.MinHeight = (int)(avgSize.y * 0.6);
            bc.ObjectsOrder = ObjectsOrder.Size;
            bc.ProcessImage(image);
            Blob[] blobs = bc.GetObjectsInformation();

            int blobWidth = 0;
            int blobHeight = 0;
            float blobAspectRatio;
            double angle;
            RotateBilinear rotate;
            ResizeBilinear resize = new ResizeBilinear((int)avgSize.x, (int)avgSize.y);
            Bitmap bmp;
            List<IntPoint> edges = new List<IntPoint>();

            for (int b = 0; b < blobs.Length; b++)
            {
                Rectangle br = blobs[b].Rectangle;
                cropFilter = new Crop(br);
                image = cropFilter.Apply(image);
                bmp = AForge.Imaging.Image.Clone(image);
                //bc.ExtractBlobsImage(image, blobs[b], false);
                //bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
                edges = bc.GetBlobsEdgePoints(blobs[b]);
                IntPoint circleCenter = FindLargestCircleCenter(edges, blobs[b].Rectangle);
                //bmp = ImageFilters.Draw(bmp, edges);

                //Highlight circle center
                //Graphics gfx = Graphics.FromImage(bmp);
                //gfx.DrawRectangle(new Pen(Color.Red, 3), circleCenter.X - 10, circleCenter.Y - 10, 20, 20);

                blobWidth = blobs[b].Rectangle.Width;
                blobHeight = blobs[b].Rectangle.Height;
                blobAspectRatio = (float)blobWidth / blobHeight;
                if((blobAspectRatio) > avgAspectRatio + 0.08)
                {
                    float test3 = avgSize.y / avgSize.x;
                    if ((blobAspectRatio - avgAspectRatio) <= 1)
                    {
                        angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90 + (1 - (blobAspectRatio - avgAspectRatio)) * 30;
                    }
                    else
                    {
                        angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90;
                    }
                    rotate = new RotateBilinear(angle, false);
                    image = rotate.Apply(image);
                    //bmp = rotate.Apply(bmp);
                }
                image = resize.Apply(image);
                //bmp = resize.Apply(bmp);

                //image = cropFilter.Apply(image);
                //image = maxBlobFilter.Apply(image);
                int scannedPixels = 0;
                int matches = 0;
                float test = 0;
                float threshold = (float)similarityRate / 100;
                int imgHeight, imgWidth;
                
                for (int i = 0; i < cycles; i++)
                {
                    for (int smpl = 0; smpl < 10; smpl++)
                    {
                        if (image.Size.Width < samples[i, smpl].Size.Width)
                            imgWidth = image.Size.Width;
                        else
                            imgWidth = samples[i, smpl].Size.Width;
                        if (image.Size.Height < samples[i, smpl].Size.Height)
                            imgHeight = image.Size.Height;
                        else
                            imgHeight = samples[i, smpl].Size.Height;
                        for (int y = 0; y < imgHeight; y += 3)
                            for (int x = 0; x < imgWidth; x += 3)
                            {
                                scannedPixels++;
                                lock (samples[i, smpl])
                                {
                                    lock (image)
                                    {
                                        if (image.GetPixel(x, y).Equals(samples[i, smpl].GetPixel(x, y)))
                                        {
                                            matches++;
                                        }
                                    }
                                }
                            }
                        test = (float)matches / (float)scannedPixels;
                        if (test >= threshold)
                        {
                            //bc.ExtractBlobsImage(image, blobs[b], false);
                            //bmp.Save("detect" + detectedNum + "o.bmp");
                            //image.Save("detect" + detectedNum + "r.bmp");
                            detectedNum++;
                            return new IntPoint(dimensions.X - circleCenter.X, circleCenter.Y);

                            //return new IntPoint(image.Width - (int)blobs[b].CenterOfGravity.X, (int)blobs[b].CenterOfGravity.Y);
                        }
                        matches = 0;
                        scannedPixels = 0;
                    }
                }
            }
            return new IntPoint();
        }