A class for checking simple geometrical shapes.

The class performs checking/detection of some simple geometrical shapes for provided set of points (shape's edge points). During the check the class goes through the list of all provided points and checks how accurately they fit into assumed shape.

All the shape checks allow some deviation of points from the shape with assumed parameters. In other words it is allowed that specified set of points may form a little bit distorted shape, which may be still recognized. The allowed amount of distortion is controlled by two properties (MinAcceptableDistortion and RelativeDistortionLimit), which allow higher distortion level for bigger shapes and smaller amount of distortion for smaller shapes. Checking specified set of points, the class calculates mean distance between specified set of points and edge of the assumed shape. If the mean distance is equal to or less than maximum allowed distance, then a shape is recognized. The maximum allowed distance is calculated as: maxDitance = max( minAcceptableDistortion, relativeDistortionLimit * ( width + height ) / 2 ) , where width and height is the size of bounding rectangle for the specified points.

See also AngleError and LengthError properties, which set acceptable errors for polygon sub type checking done by CheckPolygonSubType method.

See the next article for details about the implemented algorithms: Detecting some simple shapes in images.

Sample usage:

private List<IntPoint> idealCicle = new List<IntPoint>( ); private List<IntPoint> distorredCircle = new List<IntPoint>( ); System.Random rand = new System.Random( ); // generate sample circles double radius = 100; for ( int i = 0; i < 360; i += 10 ) { double angle = (double) i / 180 * System.Math.PI; // add point to ideal circle idealCicle.Add( new IntPoint( (int) ( radius * System.Math.Cos( angle ) ), (int) ( radius * System.Math.Sin( angle ) ) ) ); // add a bit distortion for distorred cirlce double distorredRadius = radius + rand.Next( 7 ) - 3; distorredCircle.Add( new IntPoint( (int) ( distorredRadius * System.Math.Cos( angle ) ), (int) ( distorredRadius * System.Math.Sin( angle ) ) ) ); } // check shape SimpleShapeChecker shapeChecker = new SimpleShapeChecker( ); if ( shapeChecker.IsCircle( idealCicle ) ) { // ... } if ( shapeChecker.CheckShapeType( distorredCircle ) == ShapeType.Circle ) { // ... }
        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();
        }
예제 #2
0
        /// <summary>
        /// Méthode qui analyse les images envoyées par le client
        /// Repère les formes présentes, les découpe et les enregistre en ficiers distincts
        /// </summary>
        public void ProcessImage()
        {
            using (CamCapturer.CamCapturer cam = new CamCapturer.CamCapturer())
            {
                Picture = cam.GetCapture();
                Copy = cam.GetCapture();
            }

            ShapeChecker = new SimpleShapeChecker();
            ShapeAnalyser = new BlobCounter();
            string date = DateTime.Now.Date.ToString("dMyyyy");
            FolderName = string.Format("Kuhlschrank-{0}", date);

            ShapeAnalyser.FilterBlobs = true;
            ShapeAnalyser.MinHeight = 200;
            ShapeAnalyser.MinWidth = 500;
            Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), FolderName));

            BitmapData bitData = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), ImageLockMode.ReadWrite, Picture.PixelFormat);

            ColorFiltering filter = new ColorFiltering();

            filter.Red = new IntRange(0, 64);
            filter.Green = new IntRange(0, 64);
            filter.Blue = new IntRange(0, 64);
            filter.FillOutsideRange = false;

            filter.ApplyInPlace(bitData);

            ShapeAnalyser.ProcessImage(bitData);
            Blob[] blobs = ShapeAnalyser.GetObjectsInformation();
            Picture.UnlockBits(bitData);

            for (int i = 0; i < blobs.Length; i++)
            {
                List<IntPoint> edgePoints = ShapeAnalyser.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;
                ShapeChecker.IsConvexPolygon(edgePoints, out corners);

                IntPoint pt0 = corners[0];
                IntPoint pt1 = corners[1];
                IntPoint pt2 = corners[2];

                double width = Math.Sqrt(Math.Pow(pt1.X - pt0.X, 2) + Math.Pow(pt1.Y - pt0.Y, 2));
                double height = Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2) + Math.Pow(pt2.Y - pt1.Y, 2));

                Rectangle crop = new Rectangle(corners[0].X, corners[1].Y, (int)width + 50, (int)height + 50);
                Bitmap target = new Bitmap(crop.Width, crop.Height);
                using (Graphics gr = Graphics.FromImage(target))
                    gr.DrawImage(Copy, new Rectangle(0, 0, target.Width, target.Height), crop, GraphicsUnit.Pixel);

                target.Save(string.Format(@"{0}\{1}\crop{2}.jpg", Path.GetTempPath(), FolderName, i));
            }
        }
예제 #3
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 }));
                    }
                }
            }
        }
예제 #4
0
        public ImageProcessor()
        {
            shapeChecker = new SimpleShapeChecker();
            hullFinder = new GrahamConvexHull();

            blobCounter = new BlobCounter();

            HotGoal = 0;

            greenPen = new Pen(Color.FromArgb(0, 255, 0), 1);
            yellowPen = new Pen(Color.FromArgb(255, 255, 0), 1);
            redPen = new Pen(Color.FromArgb(255, 0, 0), 2);
            orangePen = new Pen(Color.FromArgb(255, 127, 0), 1);
            purplePen = new Pen(Color.FromArgb(102, 51, 153), 1);
            redBrush = new SolidBrush(Color.FromArgb(255, 0, 0));
            blueBrush = new SolidBrush(Color.FromArgb(0, 0, 255));
        }
예제 #5
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;
        }
예제 #6
0
파일: Form1.cs 프로젝트: niugm/Magic-Vision
        private void detectQuads(Bitmap bitmap)
        {
            // Greyscale
            filteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap);

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

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

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

            BlobCounter blobCounter = new BlobCounter();

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

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            filteredBitmap.UnlockBits(bitmapData);

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

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

            Graphics g = Graphics.FromImage(bm);
            g.DrawImage(filteredBitmap, 0, 0);

            Pen pen = new Pen(Color.Red, 5);
            List<IntPoint> cardPositions = new List<IntPoint>();

            // Loop through detected shapes
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;
                bool sameCard = false;

                // is triangle or quadrilateral
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    // get sub-type
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                    // Only return 4 corner rectanges
                    if ((subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rectangle) &&  corners.Count == 4)
                    {
                        // Check if its sideways, if so rearrange the corners so it's veritcal
                        rearrangeCorners(corners);

                        // Prevent it from detecting the same card twice
                        foreach (IntPoint point in cardPositions)
                        {
                            if (corners[0].DistanceTo(point) < 40)
                                sameCard = true;
                        }

                        if (sameCard)
                            continue;

                        // Hack to prevent it from detecting smaller sections of the card instead of the whole card
                        if (GetArea(corners) < 20000)
                            continue;

                        cardPositions.Add(corners[0]);

                        g.DrawPolygon(pen, ToPointsArray(corners));

                        // Extract the card bitmap
                        QuadrilateralTransformation transformFilter = new QuadrilateralTransformation(corners, 211, 298);
                        cardBitmap = transformFilter.Apply(cameraBitmap);

                        List<IntPoint> artCorners = new List<IntPoint>();
                        artCorners.Add(new IntPoint(14, 35));
                        artCorners.Add(new IntPoint(193, 35));
                        artCorners.Add(new IntPoint(193, 168));
                        artCorners.Add(new IntPoint(14, 168));

                        // Extract the art bitmap
                        QuadrilateralTransformation cartArtFilter = new QuadrilateralTransformation(artCorners, 183, 133);
                        cardArtBitmap = cartArtFilter.Apply(cardBitmap);

                        MagicCard card = new MagicCard();
                        card.corners = corners;
                        card.cardBitmap = cardBitmap;
                        card.cardArtBitmap = cardArtBitmap;

                        magicCards.Add(card);
                    }
                }
            }

            pen.Dispose();
            g.Dispose();

            filteredBitmap = bm;
        }
        private void checkShape(SimpleShapeChecker shapeChecker, List<IntPoint> edgePts)
        {
            AForge.Point center;
            float radius;
            List<IntPoint> corners;
            if(edgePts.Count>4 && shapeChecker.IsCircle(edgePts,out center,out radius)){
                //shape is a circle
                drawEllipse(center, radius);
                shapeCount[0]++;
            }
            else if(edgePts.Count>3 && shapeChecker.IsConvexPolygon(edgePts,out corners)){
                PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                if (subType == PolygonSubType.Unknown)
                {
                    shapeCount[4]++;
                }
                else if (subType == PolygonSubType.Square)
                {
                    shapeCount[2]++;
                }
                else if (subType == PolygonSubType.Rectangle)
                {
                    shapeCount[3]++;
                }
                else if (subType == PolygonSubType.Trapezoid)
                {
                    shapeCount[5]++;
                }
                else if (subType == PolygonSubType.EquilateralTriangle)
                {
                    shapeCount[1]++;
                }
                else if (subType == PolygonSubType.IsoscelesTriangle) {
                    shapeCount[1]++;
                }

                drawPolygon(corners);

            }
            else if(shapeChecker.IsTriangle(edgePts)){
                //triangle
                shapeCount[1]++;

            }
        }
예제 #8
0
        public void DetectQuads()
        {
            // Greyscale
            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
            {
                FilterBlobs = true,
                MinHeight = 125,
                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 g = Graphics.FromImage(bm);
            g.DrawImage(FilteredBitmap, 0, 0);

            var pen = new Pen((Color)new ColorConverter().ConvertFromString(Application.Current.Resources["AccentColor"].ToString()), 5);
            var cardPositions = new List<IntPoint>();

            // Loop through detected shapes
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                var edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;
                var sameCard = false;

                // is triangle or quadrilateral
                if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                {
                    if (!corners.Any())
                        return;
                    // get sub-type
                    var subType = shapeChecker.CheckPolygonSubType(corners);

                    // Only return 4 corner rectanges
                    if ((subType != PolygonSubType.Parallelogram && subType != PolygonSubType.Rectangle) || corners.Count != 4)
                        continue;

                    // Check if its sideways, if so rearrange the corners so it's veritcal
                    RearrangeCorners(corners);

                    // Prevent it from detecting the same card twice
                    foreach (var point in cardPositions)
                    {
                        var distance = corners[0].DistanceTo(point);
                        if (corners[0].DistanceTo(point) < 40)
                            sameCard = true;
                    }

                    if (sameCard)
                        continue;

                    // Hack to prevent it from detecting smaller sections of the card instead of the whole card
                    var area = GetArea(corners);

                    if (area < 20000)// || area > 35000)
                        continue;

                    cardPositions.Add(corners[0]);

                    g.DrawPolygon(pen, ToPointsArray(corners));

                    // Extract the card bitmap
                    var transformFilter = new QuadrilateralTransformation(corners, 225, 325);
                    CardBitmap = transformFilter.Apply(CameraBitmap);
                    TmpCard = new MagicCard
                    {
                        Corners = corners,
                        CardBitmap = CardBitmap
                    };
                }
            }

            pen.Dispose();
            g.Dispose();

            FilteredBitmap = bm;
        }
        /// <summary>
        /// Get rectangle contain glyphs in current frame
        /// </summary>
        /// <param name="image">Frame source</param>
        /// <param name="lists">Rectangles contain glyphs</param>
        public static void GlyphsPotentialsTracking(ref UnmanagedImage image, ref List<Rectangle> lists)
        {
            // 1 - grayscaling
            UnmanagedImage grayImage = null;

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

            // 2 - Edge detection
            DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector();
            UnmanagedImage edgesImage = edgeDetector.Apply(grayImage);

            // 3 - Threshold edges
            Threshold thresholdFilter = new Threshold(80);
            thresholdFilter.ApplyInPlace(edgesImage);

            //// ---------------- MILESTONE
            //image = edgesImage;
            //return;

            // create and configure blob counter
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.MinHeight = 32;
            blobCounter.MinWidth = 32;
            blobCounter.FilterBlobs = true;
            blobCounter.ObjectsOrder = ObjectsOrder.Size;

            // 4 - find all stand alone blobs
            blobCounter.ProcessImage(edgesImage);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            List<IntPoint> edgePoints = null;
            List<IntPoint> corners = null;
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            // 5 - check each blob
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                corners = null;

                // does it look like a quadrilateral ?
                if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                {
                    // get edge points on the left and on the right side
                    List<IntPoint> leftEdgePoints, rightEdgePoints;

                    blobCounter.GetBlobsLeftAndRightEdges(blobs[i],
                        out leftEdgePoints, out rightEdgePoints);

                    // calculate average difference between pixel values from outside of the
                    // shape and from inside
                    float diff = CalculateAverageEdgesBrightnessDifference(
                        leftEdgePoints, rightEdgePoints, grayImage);

                    // check average difference, which tells how much outside is lighter than
                    // inside on the average
                    if (diff > 20)
                    {
                        lists.Add(blobs[i].Rectangle);
                    }
                }
            }
        }
        public List<string> DetectLicensePlate(Bitmap bitmap)
        {
            Bitmap original = (Bitmap)bitmap.Clone();

            // threshold obrazku - s timto lze experimentovat a zlepsit detekci znacek v nekterych obraycich
            bitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap);
            OtsuThreshold threshold = new OtsuThreshold();
            bitmap = threshold.Apply(bitmap);

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

            // vyhledani objektu
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = 10;
            blobCounter.MinWidth = 60;

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            // detekce objektu a jeho tvaru
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            //shapeChecker.AngleError = 15;
            //shapeChecker.MinAcceptableDistortion = 1;
            //shapeChecker.RelativeDistortionLimit = 0.05f;

            List<string> results = new List<string>();

            int a = 0;
            string text;
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);

                List<IntPoint> corners;
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    // zjisteni typu (obdelnik, ...)
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                    if (corners.Count() == 4)
                    {
                        Bitmap rectangle = this.Transform(corners, original);
                        text = this.Detect(rectangle);
                        if (text.Length > 6)
                        {
                            results.Add(text);
                            rectangle.Save("temp/" + text + ".jpg");
                        }
                    }
                }
            }

            return results;
        }
        private Bitmap ProcessImage(Bitmap bitmap)
        {
            ///CROP SYSTEM

            //if (cropx1 != 0 && cropy1 != 0 && cropx2 != 0 && cropy2 != 0 && Worker.selected_square != 0)
            //{
            //    Crop crop_filter = new Crop(new Rectangle(cropx1, cropy1, cropx2, cropy2));
            //     bitmap= crop_filter.Apply(bitmap);
            //    Console.WriteLine(">Crop Cutter:> Cropped\n({0},{1}),({2},{3})", cropx1, cropy1, cropx2, cropy2);
            //}

            //if (Worker.selected_square == 0)
            //{
            //    Crop crop_filter = new Crop(new Rectangle(0, 0, bitmap.Width,bitmap.Height));
            //    bitmap = crop_filter.Apply(bitmap);
            //    //Console.WriteLine(">Crop Cutter:> RESET");
            //}
            //// step 2 - locating objects

            if (cropx1 == 0 && cropy1 == 0 && cropx2 == 0 && cropy2 == 0)
            {
                cropx1 = 0;
                cropy1 = 0;
                cropx2 = bitmap.Width;
                cropy2 = bitmap.Height;

            }
            Bitmap old = bitmap;
            Crop crop_filter = new Crop(new Rectangle(cropx1, cropy1, cropx2, cropy2));

            bitmap = crop_filter.Apply(bitmap);

            // lock image
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            //  ////invert
            // Invert inv = new Invert();
            //  // //apply the filter
            //inv.ApplyInPlace(bitmapData);

            //// create filter
            //HSLFiltering filter = new HSLFiltering();
            //// set color ranges to keep
            //filter.Hue = new IntRange(90, 300);
            //filter.Saturation = new Range(0.0f, .5f);
            //filter.Luminance = new Range(0f, 1);
            //// apply the filter
            //filter.ApplyInPlace(bitmapData);

            //EuclideanColorFiltering filter = new EuclideanColorFiltering();
            //// set center colol and radius
            //filter.CenterColor = new RGB(209, 206, 196);
            //filter.Radius = 150;
            //// apply the filter
            //filter.ApplyInPlace(bitmapData);

            //// create filter
            ChannelFiltering filter = new ChannelFiltering();
            //// set channels' ranges to keep

            Invert inv = new Invert();

            //// //apply the filter

            inv.ApplyInPlace(bitmapData);

            if (red_max > 255)
            {
                red_max = 255;
                Console.WriteLine("1THRESHOLD OVERIDE");
            }
            if (blue_max > 255)
            {
                blue_max = 255;
                Console.WriteLine("2THRESHOLD OVERIDE");
            }
            if (green_max > 255)
            {
                green_max = 255;
                Console.WriteLine("3THRESHOLD OVERIDE");
            }
            if (red > 255)
            {
                red = 254;
                Console.WriteLine("4THRESHOLD OVERIDE");
            }
            if (blue > 255)
            {
                blue = 254;
                Console.WriteLine("5THRESHOLD OVERIDE");
            }
            if (green > 255)
            {
                green = 254;
                Console.WriteLine("6THRESHOLD OVERIDE");
            }

            if (red < 0)
            {
                red = 1;
                Console.WriteLine("7THRESHOLD UNDERIDE");
            }
            if (blue < 0)
            {
                blue = 1;
                Console.WriteLine("8THRESHOLD UNDERIDE");
            }
            if (green < 0)
            {
                green = 1;
                Console.WriteLine("9THRESHOLD UNDERIDE");
            }

            if (red_max < 0)
            {
                red_max = 255;
                Console.WriteLine("10THRESHOLD UNDERIDE");
            }
            if (blue_max < 0)
            {
                blue_max = 255;
                Console.WriteLine("11THRESHOLD UNDERIDE");
            }
            if (green_max < 0)
            {
                green_max = 255;
                Console.WriteLine("13THRESHOLD UNDERIDE");
            }

            if (red_max < red)
            {
                Console.WriteLine("14THRESHOLD UNION ERROR");
                red = 0;
                red_max = 255;
            }

            if (blue_max < blue)
            {
                blue = 0;
                Console.WriteLine("15THRESHOLD UNION ERROR");
                blue_max = 255;
            }
            if (green_max < green)
            {
                green = 0;
                green_max = 255;
                Console.WriteLine("16THRESHOLD UNION ERROR");
            }

            file.WriteLine("R: " + red + " R_M: " + red_max);
            file.WriteLine("G: " + green + " G_M: " + green_max);
            file.WriteLine("B: " + blue + " B_M: " + blue_max);
            file.WriteLine("EOE");
            //file.Close();
            filter.Red = new IntRange(red, red_max);
            filter.Green = new IntRange(green, green_max);
            filter.Blue = new IntRange(blue, blue_max);
            //// apply the filter
            filter.ApplyInPlace(bitmapData);

            ////invert

            //edge

            //CannyEdgeDetector edge_filter = new CannyEdgeDetector();
            //// apply the filter
            //edge_filter.ApplyInPlace(bitmapData);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = blob_size * 3;
            blobCounter.MinWidth = blob_size * 4;

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            Graphics g = Graphics.FromImage(bitmap);
            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
            double curdist = 0;
            double leastdist = 100;
            //List<IntPoint> bestcorn;//promoted to super
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners; // the list of x,y coordinates.  corners(list)->corner(intpoint)->[x,y]

                // is triangle or quadrilateral

                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    cornide = corners;
                    // get sub-type

                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
                    Pen pen;
                    if (subType == PolygonSubType.Rectangle || subType == PolygonSubType.Trapezoid || subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rhombus || subType == PolygonSubType.Square || subType == PolygonSubType.Unknown)
                    {

                        if (corners.Count == 4)
                        {
                            pen = redPen;
                            IntPoint[] array_of_corners = corners.ToArray();//array_of_corners is now an array of corners
                            if (((732 / avdisty(array_of_corners)) + .222) < ((989 / avdistx(array_of_corners)) + 3.37))
                            {
                                curdist = ((732 / avdisty(array_of_corners)) + .222);//from our graph
                            }
                            else
                            {
                                curdist = ((989 / avdistx(array_of_corners)) + 3.37);//from our graph
                            }

                            //if (Worker.selected_square == 1)
                            //{
                            //    Console.WriteLine("called\n");
                            //    IntPoint one = array_of_corners[0];
                            //    IntPoint two = array_of_corners[3];
                            //    cropx1 = one.X - 5;
                            //    cropy1 = one.Y - 5;
                            //    cropx2 = two.X + 5;
                            //    cropy2 = two.Y + 5;
                            //}
                            //else if (i == Worker.selected_square - 1 && Worker.selected_square != 1)
                            //{
                            //    Console.WriteLine("called\n");
                            //    IntPoint one = array_of_corners[0];
                            //    IntPoint two = array_of_corners[3];
                            //    cropx1 = one.X - 5;
                            //    cropy1 = one.Y - 5;
                            //    cropx2 = two.X + 5;
                            //    cropy2 = two.Y + 5;
                            //}
                            //if (Worker.selected_square == 0)
                            //{
                            //    cropx1 = 0;
                            //    cropy1 = 0;
                            //    cropx2 = 0;
                            //    cropy2 = 0;
                            //}

                            if (Worker.selected_square == 0)//PREDATOR VISION
                            {

                                if (curdist < leastdist)
                                {
                                    //  Console.WriteLine((abs(array_of_corners[0].Y - array_of_corners[1].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)));
                                    //if ((abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) < 1.25 && (abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) > .5)
                                    if (true)
                                    {

                                        leastdist = curdist;
                                        if (leastdist < 55 && leastdist > 2)
                                        {

                                            double angle = (array_of_corners[0].X + array_of_corners[3].X) / 2;
                                            Console.WriteLine("0: " + array_of_corners[0].X + " 1: " + array_of_corners[1].X + " 2: " + array_of_corners[2].X + " 3: " + array_of_corners[3].X);
                                            Server.SetData(((array_of_corners[0].X + array_of_corners[1].X) / 2), 1);
                                            Console.WriteLine("PREDATOR: " + Server.GetData(1));
                                            Console.WriteLine(leastdist);
                                            Server.SetData(leastdist, 0);

                                            bestcorn = corners;//superify?
                                            //g.DrawPolygon(pen, ToPointsArray(bestcorn));//leave here as a comment

                                            IntPoint ones = array_of_corners[0];
                                            PointF string_draw = new PointF(ones.X, ones.Y);
                                            SolidBrush tbrush = new SolidBrush(Color.Red);
                                            try
                                            {
                                                if (string_draw.X != 0 && string_draw.Y != 0)
                                                {
                                                    g.DrawString(n.ToString(), this.Font, tbrush, string_draw);
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("{0} in {1} ({2},{3})", e.Message, e.StackTrace, string_draw.X, string_draw.Y);
                                            }

                                        }

                                    }
                                }
                                try
                                {

                                    Graphics global_graphics_predator = Graphics.FromImage(bitmap);
                                    Pen penc = new Pen(Color.YellowGreen, 2);

                                    //g.DrawPolygon(penc, ToPointsArray(bestcorn));
                                    global_graphics_predator.DrawPolygon(penc, ToPointsArray(bestcorn));
                                    global_graphics_predator.DrawLine(penc, new System.Drawing.Point(320, 1), new System.Drawing.Point(320, 479));
                                    //bitmap = global_bitmap;

                                }
                                catch (Exception e)
                                {
                                }

                                yellowPen.Dispose();
                                redPen.Dispose();
                                greenPen.Dispose();
                                bluePen.Dispose();
                                brownPen.Dispose();
                                g.Dispose();

                                return bitmap;
                            }
                            else
                            {

                                int sel_least_dist = Worker.selected_square;
                                sel_least_dist *= 3;//threefeet
                                sel_least_dist -= 1;
                                int sel_max_dist = sel_least_dist + 5;
                                Console.WriteLine(sel_least_dist);
                                Console.WriteLine(sel_max_dist);
                                //Console.WriteLine(sel_least_dist + " " + sel_max_dist);

                                if (curdist < leastdist && curdist > sel_least_dist && curdist < sel_max_dist)
                                {
                                    //  Console.WriteLine((abs(array_of_corners[0].Y - array_of_corners[1].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)));
                                    //if ((abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) < 1.25 && (abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) > .5)
                                    if (true)//todo
                                    {

                                        leastdist = curdist;
                                        if (leastdist < 55 && leastdist > 2)
                                        {

                                            // Console.WriteLine("0: " + array_of_corners[0].X + " 1: " + array_of_corners[1].X + " 2: " + array_of_corners[2].X + " 3: " + array_of_corners[3].X);

                                            Server.SetData(((array_of_corners[0].X + array_of_corners[1].X) / 2), 1);
                                            Console.WriteLine(Server.GetData(1));
                                            //Console.WriteLine(leastdist);
                                            Server.SetData(leastdist, 0);
                                            bestcorn = corners;//superify?
                                            //g.DrawPolygon(pen, ToPointsArray(bestcorn));//leave here as a comment

                                            IntPoint ones = array_of_corners[0];
                                            PointF string_draw = new PointF(ones.X, ones.Y);
                                            SolidBrush tbrush = new SolidBrush(Color.Red);
                                            try
                                            {
                                                if (string_draw.X != 0 && string_draw.Y != 0)
                                                {
                                                    g.DrawString(n.ToString(), this.Font, tbrush, string_draw);
                                                    // glob.DrawLine(penc, new System.Drawing.Point(10, 10), new System.Drawing.Point(20, 20));
                                                    //g.DrawLine(pen, new System.Drawing.Point(10, 10), new System.Drawing.Point(20, 20));
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("{0} in {1} ({2},{3})", e.Message, e.StackTrace, string_draw.X, string_draw.Y);
                                            }

                                        }

                                    }
                                }
                            }

                            //pen = (corners.Count == 4) ? redPen : bluePen;
                        }//TODO get rid of anything that ISNT drawn, eg corner
                    }

                    //else
                    //{

                    //    pen = (corners.Count == 4) ? brownPen : greenPen;

                    //}

                }

            }
            //Console.WriteLine(leastdist); how dod oyo

            //double leastdist = 0;
            //for (int i = 0, n = blobs.Length; i < n; i++)
            //{
            //    try
            //    {
            //        List<IntPoint> filterlist;
            //        filterlist = cornide;

            //        IntPoint[] filter_corners = filterlist.ToArray();

            //        double currentdist = 0;
            //        for (int corner_count = 0; corner_count < filter_corners.Length; corner_count++)
            //        {

            //            IntPoint one_f = filter_corners[corner_count];
            //            corner_count++;
            //            IntPoint two_f = filter_corners[corner_count];
            //            corner_count++;
            //            IntPoint three_f = filter_corners[corner_count];
            //            corner_count++;
            //            IntPoint four_f = filter_corners[corner_count];

            //            double y_average_a = ((double)one_f.Y + (double)two_f.Y) / 2;
            //            double y_average_b = ((double)three_f.Y + (double)four_f.Y) / 2;
            //            double averaged_dist = y_average_b - y_average_a;
            //            currentdist = ((732 / averaged_dist) + .222);//from our graph
            //            if (currentdist <= leastdist)
            //            {
            //                leastdist = currentdist;
            //                Pen pencil = redPen;

            //                g.DrawPolygon(pencil, ToPointsArray(filterlist));
            //            }

            //        }

            //    }
            //    catch
            //    {
            //        //do nothING
            //    }

            //}
            //Console.WriteLine(leastdist);

            try
            {

                Graphics global_graphics = Graphics.FromImage(global_bitmap);
                Pen penc = new Pen(Color.YellowGreen, 2);
                {
                    //g.DrawPolygon(penc, ToPointsArray(bestcorn));
                    global_graphics.DrawPolygon(penc, ToPointsArray(bestcorn));
                    global_graphics.DrawLine(penc, new System.Drawing.Point(320, 1), new System.Drawing.Point(320, 479));

                    bitmap = global_bitmap;
                }
            }
            catch (Exception e)
            {
            }
            try
            {
                g.DrawLine(redPen, 220, 1, 220, 100);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
                Console.WriteLine(e.InnerException);

            }
            yellowPen.Dispose();
            redPen.Dispose();
            greenPen.Dispose();
            bluePen.Dispose();
            brownPen.Dispose();

            g.Dispose();

            return bitmap;
        }
예제 #12
0
        /// <summary>
        /// Gets the squares in the image
        /// </summary>
        /// <param name="cubeFace">Image to get the squares</param>
        /// <param name="minWidth">Minimum square width</param>
        /// <param name="minHeight">Minimum square height</param>
        /// <returns>Returns the list with the squares.</returns>
        public List<Rectangle> GetSquares(System.Drawing.Image cubeFace, int minWidth, int minHeight)
        {
            Squares = new List<Rectangle>();
            Bitmap bitmap = new Bitmap(cubeFace);
            // lock image
            System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);

            // step 1 - turn background to black
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red = new AForge.IntRange(0, 64);
            colorFilter.Green = new AForge.IntRange(0, 64);
            colorFilter.Blue = new AForge.IntRange(0, 64);
            colorFilter.FillOutsideRange = false;

            colorFilter.ApplyInPlace(bitmapData);

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();

            blobCounter.FilterBlobs = true;
            blobCounter.MinHeight = minHeight;
            blobCounter.MinWidth = minWidth;

            blobCounter.ProcessImage(bitmapData);
            AForge.Imaging.Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                List<IntPoint> corners;
                // is triangle or quadrilateral
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners) && corners.Count == 4)
                {
                    Squares.Add(blobs[i].Rectangle);
                }
            }
            return Squares;
        }
예제 #13
0
        /// <summary>
        /// Initialize the needed components for this class.
        /// </summary>
        public void Initialize()
        {
            this.shapeChecker = new SimpleShapeChecker();
            this.CellList = new List<ColonyModel>();
            this.blobList = new List<Blob>();

            // SET COLOR RANGE FOR BACKGROUND
            RangeRed = new IntRange(255,255);
            RangeGreen = new IntRange(255, 255);
            RangeBlue = new IntRange(255, 255);
        }
예제 #14
0
        private void ParseImage(int imageId)
        {
            DateTime startTime = DateTime.Now;
            Console.WriteLine(string.Format("Start parsing {0}", startTime));

            string difImagePath = "";

            if (imageId >= 0) difImagePath = DifBoardImages[imageId];

            Bitmap orig;
            Bitmap dif;

            try
            {
                Console.WriteLine("Load files");

                orig = (Bitmap)Bitmap.FromFile(OriginalBoardImage);

                if (imageId >= 0)
                    dif = (Bitmap)Bitmap.FromFile(difImagePath);
                else
                    dif = (Bitmap)internalImageContainer;
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERR: " + ex.Message);
                Console.WriteLine(ex.StackTrace);

                // kill any exception due to missing files
                return;
            }

            Difference filter = new Difference(orig);
            dif = filter.Apply(dif);
            Console.WriteLine("Apply difference filter");

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.ProcessImage(dif);
            Console.WriteLine("Blob counting");
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // create Graphics object to draw on the image and a pen
            Graphics g = Graphics.FromImage(dif);
            Pen redPen = new Pen(Color.Red, 3);
            Pen bluePen = new Pen(Color.Blue, 1);
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            // check each object and draw circle around objects, which
            // are recognized as circles
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);

                Console.Write(string.Format("Detected {0} points", edgePoints.Count));

                if (edgePoints.Count <= 1)
                    continue;

                List<IntPoint> points = new List<IntPoint>();

                if (shapeChecker.IsQuadrilateral(edgePoints))
                    Console.Write(", quadrilateral");
                else if (shapeChecker.IsConvexPolygon(edgePoints, out points))
                    Console.Write(", convex poligon");
                else if (shapeChecker.IsTriangle(edgePoints, out points))
                    Console.Write(", triangle");

                Pen usePen = shapeChecker.IsQuadrilateral(edgePoints) ? redPen : bluePen;

                int centerX = edgePoints[0].X;
                int centerY = edgePoints[0].Y;

                for (int j = 0; j < edgePoints.Count - 1; j++)
                {
                    centerX += edgePoints[j + 1].X;
                    centerY += edgePoints[j + 1].Y;

                    g.DrawLine(usePen, edgePoints[j].X, edgePoints[j].Y, edgePoints[j + 1].X, edgePoints[j + 1].Y);
                }

                // add last point
                centerX += edgePoints[edgePoints.Count - 1].X;
                centerY += edgePoints[edgePoints.Count - 1].Y;

                g.DrawLine(usePen
                    , edgePoints[0].X, edgePoints[0].Y
                    , edgePoints[edgePoints.Count - 1].X, edgePoints[edgePoints.Count - 1].Y);

                Console.WriteLine(string.Format("\nOriginal (x, y): {0}, {1}"
                    , new object[] {
                        (centerX / edgePoints.Count), (centerY / edgePoints.Count)
                    }));
                Console.WriteLine(string.Format("Detected (x, y): {0}, {1}"
                    , (centerX / edgePoints.Count)
                    , (centerY / edgePoints.Count)
                ));
            }

            redPen.Dispose();
            bluePen.Dispose();
            g.Dispose();

            //DifI = dif;
            dif.Save(dirPath + "processed-dif.jpg");

            Console.WriteLine(string.Format("Duration: {0} sec", (DateTime.Now - startTime)));
        }
예제 #15
0
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            // Open your image
            string path = file.FullName;
            Bitmap image = (Bitmap)Bitmap.FromFile(path);

            // locating objects
            BlobCounter blobCounter = new BlobCounter();

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

            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<System.Drawing.Point> Points = new List<System.Drawing.Point>();
                        bool flag = false;
                        foreach (var point in cornerPoints)
                        {
                            if (point.X == 0 && point.Y == 0)
                                flag = true;
                            Points.Add(new System.Drawing.Point(point.X, point.Y));
                        }

                        if (flag)
                            continue;
                        Graphics g = Graphics.FromImage(image);
                        g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray());
                        _rect++;
                        image.Save("result.png");
                    }
                }
                else if (shapeChecker.IsTriangle(edgePoints, out cornerPoints))
                {
                    List<System.Drawing.Point> Points = new List<System.Drawing.Point>();
                    foreach (var point in cornerPoints)
                    {
                        Points.Add(new System.Drawing.Point(point.X, point.Y));
                    }

                    Graphics g = Graphics.FromImage(image);
                    g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray());
                    _tri++;
                    image.Save("result.png");
                }
            }
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.UriSource = new Uri(file.Directory + @"\result.png");
            bi.EndInit();
            IMG_AFTER.Source = bi;
            TB_OUT.Text = "На картинке " + _rect-- + " прямоугольника \r\nИ " + _tri + " треугольника";
        }
예제 #16
0
        //returns corners of found rectangle
        public List<IntPoint> getCorners(Bitmap toEdit)
        {
            Bitmap bitmap = new Bitmap(toEdit);
            List<IntPoint> corners = new List<IntPoint>();
            List<IntPoint> oneBlob = new List<IntPoint>();
            // lock image
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            //black background
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red = new IntRange(0, 64);
            colorFilter.Green = new IntRange(0, 64);
            colorFilter.Blue = new IntRange(0, 64);
            colorFilter.FillOutsideRange = false;

            colorFilter.ApplyInPlace(bitmapData);

            //locate figurres
            BlobCounter blobCounter = new BlobCounter();

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

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            //check object type
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            Graphics g = Graphics.FromImage(bitmap);

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

                // check if trainge of rectangle
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    // get subtype (is rectangle?)
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                    if (subType == PolygonSubType.Rectangle)
                    {
                        for (int j = 0; j < 4; j++)
                        {
                            for (int k = 0; k < 3; k++)
                            {
                                IntPoint temp = new IntPoint();
                                if (j < 3)
                                {
                                    if (corners[k].Y > corners[k + 1].Y)
                                    {
                                        temp = corners[k];
                                        corners[k] = corners[k + 1];
                                        corners[k + 1] = temp;
                                    }

                                }
                            }
                        }
                        //sort list of corners
                        if (corners[0].X > corners[1].X)
                        {
                            IntPoint temp = new IntPoint();
                            temp = corners[0];
                            corners[0] = corners[1];
                            corners[1] = temp;
                        }

                        if (corners[3].X > corners[2].X)
                        {
                            IntPoint temp = new IntPoint();
                            temp = corners[2];
                            corners[2] = corners[3];
                            corners[3] = temp;
                        }

                        int blobHeigth = Math.Abs(corners[3].Y - corners[0].Y);
                        int blobWidth = Math.Abs(corners[1].X - corners[0].X);

                        if (blobHeigth < blobWidth)
                        {
                            //   float ratio = blobWidth / blobHeigth;

                            //  if(ratio > 1)
                            oneBlob = corners;
                        }
                    }

                }
            }

            g.Dispose();

            // put new image to clipboard
            Clipboard.SetDataObject(bitmap);
            // and to picture box
            // pictureBox.Image = bitmap;
            return oneBlob;
            // UpdatePictureBoxPosition();
        }
예제 #17
0
        // Process image
        public Bitmap ProcessImage(Bitmap toEdit)
        {
            Bitmap bitmap = new Bitmap(toEdit);
            List<IntPoint> corners = new List<IntPoint>();
            // lock image
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite, bitmap.PixelFormat);

            //black background
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red = new IntRange(0, 64);
            colorFilter.Green = new IntRange(0, 64);
            colorFilter.Blue = new IntRange(0, 64);
            colorFilter.FillOutsideRange = false;

            colorFilter.ApplyInPlace(bitmapData);

            //locating figures
            BlobCounter blobCounter = new BlobCounter();

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

            blobCounter.ProcessImage(bitmapData);
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);

            //check type of figure
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            Graphics g = Graphics.FromImage(bitmap);

            Pen redPen = new Pen(Color.Red, 2);       // pen to colour egdes

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

                // is triangle or rectangle
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    // get subtype (is rectangle?)
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                    Pen pen;

                    /*
                    if (subType == PolygonSubType.Unknown)
                    {
                        pen = (corners.Count == 4) ? redPen : bluePen;
                    }
                    else
                    {
                        pen = (corners.Count == 4) ? brownPen : greenPen;
                    }
                    */

                    if (subType == PolygonSubType.Rectangle)
                    {
                        int blobHeigth = Math.Abs(corners[3].Y - corners[0].Y);
                        int blobWidth = Math.Abs(corners[1].X - corners[0].X);

                        if (blobHeigth < blobWidth)
                        {
                            pen = redPen;

                            g.DrawPolygon(pen, ToPointsArray(corners));
                        }
                    }

                }
            }

            redPen.Dispose();

            g.Dispose();

            Clipboard.SetDataObject(bitmap);
            // and to picture box
            // pictureBox.Image = bitmap;
            return bitmap;
            // UpdatePictureBoxPosition();
        }
예제 #18
0
        // Process image
        private void ProcessImage( Bitmap bitmap )
        {
            // lock image
            BitmapData bitmapData = bitmap.LockBits(
                new Rectangle( 0, 0, bitmap.Width, bitmap.Height ),
                ImageLockMode.ReadWrite, bitmap.PixelFormat );

            // step 1 - turn background to black
            ColorFiltering colorFilter = new ColorFiltering( );

            colorFilter.Red   = new IntRange( 0, 64 );
            colorFilter.Green = new IntRange( 0, 64 );
            colorFilter.Blue  = new IntRange( 0, 64 );
            colorFilter.FillOutsideRange = false;

            colorFilter.ApplyInPlace( bitmapData );

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter( );

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

            blobCounter.ProcessImage( bitmapData );
            Blob[] blobs = blobCounter.GetObjectsInformation( );
            bitmap.UnlockBits( bitmapData );

            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker( );

            Graphics g = Graphics.FromImage( bitmap );
            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 = 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 ) )
                {
                    g.DrawEllipse( yellowPen,
                        (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 ) )
                    {
                        // get sub-type
                        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( );

            // put new image to clipboard
            Clipboard.SetDataObject( bitmap );
            // and to picture box
            pictureBox.Image = bitmap;

            UpdatePictureBoxPosition( );
        }
예제 #19
0
        // Summary - Gets the exterior rectangles.
        /***************
         * It uses a different JPEG altogether due to bpp issue (only 24 or 32 is acceptable).
         * Selects the rectangles on the basis of area (around 350 to 400).
         * Sends the quadrilaterals (4 of them) with their 4 coordinates (each) to DecideCorners for trimming.
         */
        public void PreProcess()
        {
            Bitmap bitmap = this.scanned_image;
            List<List<IntPoint>> QuadCorners = new List<List<IntPoint>>(4);

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

            // step 1 - turn background to black
            ColorFiltering colorFilter = new ColorFiltering();

            colorFilter.Red = new IntRange(0, 64);
            colorFilter.Green = new IntRange(0, 64);
            colorFilter.Blue = new IntRange(0, 64);
            colorFilter.FillOutsideRange = false;
            //MessageBox.Show(bitmapData.PixelFormat.ToString());
            colorFilter.ApplyInPlace(bitmapData);

            // step 2 - locating objects
            BlobCounter blobCounter = new BlobCounter();

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

            blobCounter.ProcessImage(bitmapData);   
            Blob[] blobs = blobCounter.GetObjectsInformation();
            bitmap.UnlockBits(bitmapData);
            
            // step 3 - check objects' type and highlight
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            //int count = 0;
            Pen redPen = new Pen(Color.Red, 2);
            Graphics g = Graphics.FromImage(bitmap);
            
            // Threshold area values for rectangles. It doesnt have a specific equation for the value based on threshold.
            // Values have been tested and set accordingly.
            int area_upper = 0, area_lower = 0;
            if (Scanner_DPI.dpi_value == 200)
            {
                area_lower = 2000;
                area_upper = 3000;
            }
            else if (Scanner_DPI.dpi_value == 300)
            {
                area_lower = 5000;
                area_upper = 6000;
            }
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);

                List<IntPoint> corners;

                // is quadrilateral
                if (shapeChecker.IsConvexPolygon(edgePoints, out corners))
                {
                    // get sub-type
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);

                        if (subType == PolygonSubType.Rectangle && blobs[i].Area > area_lower && blobs[i].Area < area_upper)
                        {
                            //g.DrawPolygon(redPen, ToPointsArray(corners));
                            QuadCorners.Add(corners);

                        }
                }
            }
            this.scanned_image = DecideCorners(QuadCorners);
        }
예제 #20
0
파일: Form1.cs 프로젝트: strofos/grigore
        private void ParseImage(int imageId)
        {
            DateTime startTime = DateTime.Now;
            labelDetection.Text = "";

            string difImagePath = "";

            if(imageId >= 0) difImagePath = DifBoardImages[imageId];

            Bitmap orig;
            Bitmap dif;

            try
            {
                orig = (Bitmap)Bitmap.FromFile(OriginalBoardImage);

                if (imageId >= 0)
                    dif = (Bitmap)Bitmap.FromFile(difImagePath);
                else
                    dif = (Bitmap)pictureBoxGenerated.Image;
            }
            catch {
                // kill any exception due to missing files
                return;
            }

            pictureBoxOrig.Image = dif;

            Difference filter = new Difference(orig);
            dif = filter.Apply(dif);

            BlobCounter blobCounter = new BlobCounter();
            blobCounter.ProcessImage(dif);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // create Graphics object to draw on the image and a pen
            Graphics g = Graphics.FromImage(dif);
            Pen redPen = new Pen(Color.Red, 3);
            Pen bluePen = new Pen(Color.Blue, 1);
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            // check each object and draw circle around objects, which
            // are recognized as circles
            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);

                labelDetection.Text = string.Format("{0} points", edgePoints.Count);

                if (edgePoints.Count <= 1)
                    continue;

                List<IntPoint> points = new List<IntPoint>();

                if (shapeChecker.IsQuadrilateral(edgePoints))
                    labelDetection.Text += ", quadrilateral";
                else if (shapeChecker.IsConvexPolygon(edgePoints, out points))
                    labelDetection.Text += ", convex poligon";
                else if (shapeChecker.IsTriangle(edgePoints, out points))
                    labelDetection.Text += ", triangle";

                Pen usePen = shapeChecker.IsQuadrilateral(edgePoints) ? redPen : bluePen;

                int centerX = edgePoints[0].X;
                int centerY = edgePoints[0].Y;
                int minX = centerX;
                int minY = centerY;
                int maxX = centerX;
                int maxY = centerY;
                for (int j = 0; j < edgePoints.Count - 1; j++)
                {
                    centerX += edgePoints[j + 1].X;
                    centerY += edgePoints[j + 1].Y;

                    if (edgePoints[j + 1].X < minX) minX = edgePoints[j + 1].X;
                    if (edgePoints[j + 1].Y < minY) minY = edgePoints[j + 1].Y;
                    if (edgePoints[j + 1].X > maxX) maxX = edgePoints[j + 1].X;
                    if (edgePoints[j + 1].Y > maxX) maxX = edgePoints[j + 1].Y;

                    g.DrawLine(usePen, edgePoints[j].X, edgePoints[j].Y, edgePoints[j + 1].X, edgePoints[j + 1].Y);
                }

                g.DrawLine(usePen
                    , edgePoints[0].X, edgePoints[0].Y
                    , edgePoints[edgePoints.Count - 1].X, edgePoints[edgePoints.Count - 1].Y);

                labelDetectedPosition.Text = string.Format("{0}, {1}"
                    , new object[] {
                        (centerX / edgePoints.Count), (centerY / edgePoints.Count)
                        //, maxX - minX, maxY - minY
                    });
                labelDetectionOffset.Text = string.Format("{0}, {1}"
                    , Grigore.Position.X - (centerX / edgePoints.Count)
                    , Grigore.Position.Y - (centerY / edgePoints.Count)
                );
            }

            redPen.Dispose();
            bluePen.Dispose();
            g.Dispose();

            pictureBoxRoboBoard.Image = dif;

            labelDetection.Text = string.Format("{1}, {0} sec", (DateTime.Now - startTime), labelDetection.Text);
        }
예제 #21
0
        public void blob_detect ()
        {
            Bitmap image = this.scanned_image;
            BlobCounter blob = new BlobCounter();
            blob.FilterBlobs = false;
            
            int blob_ht_width = 30;
            blob.MinHeight = blob_ht_width;
            blob.MinWidth = blob_ht_width;
            blob.ProcessImage(image);
            
            Blob[] b = blob.GetObjectsInformation();
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
            /*blob_counter.Text = b.Length.ToString();
            Graphics g = Graphics.FromImage(image2);
            Pen yellowPen = new Pen(Color.Yellow, 5);
            Pen redPen = new Pen(Color.Red, 5);
            Pen greenPen = new Pen(Color.Green, 5);
            int b_counter = 0;
             */
            for (int i = 0, n = b.Length; i < n; i++)
            {
                List<IntPoint> edgePoints = blob.GetBlobsEdgePoints(b[i]);
                List<IntPoint> edges = new List<IntPoint>();
                AForge.Point center;
                float radius;

                if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                
                    if (b[i].Fullness * 100 >= 40 && b[i].Fullness * 100 < 100 && radius > 10)
                    {
                        Coordinate coor = new Coordinate(center.X, center.Y);
                        BLOB blb = new BLOB(coor, radius);
                        useful.Add(blb);
                    }   
                }    
            }
            
        }
예제 #22
0
        public ActionResult Index(string Data, int Smallest = 3, int Largest = 6, HttpPostedFileBase file = null)
        {
            string base64Image = null;
            if (file != null)
            {
                //try to determine data from posted file
                var bitmap = new Bitmap(file.InputStream);

                // lock image
                BitmapData bitmapData = bitmap.LockBits(
                    new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                // step 1 - turn background to black
                var filter = new Invert();
                filter.ApplyInPlace(bitmapData);

                ColorFiltering colorFilter = new ColorFiltering();

                colorFilter.Red = new IntRange(0, 64);
                colorFilter.Green = new IntRange(0, 64);
                colorFilter.Blue = new IntRange(0, 64);
                colorFilter.FillOutsideRange = false;

                colorFilter.ApplyInPlace(bitmapData);

                // step 2 - locating objects
                BlobCounter blobCounter = new BlobCounter();

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

                blobCounter.ProcessImage(bitmapData);
                var blobs = blobCounter.GetObjectsInformation();
                bitmap.UnlockBits(bitmapData);
                base64Image = bitmap.ToBase64();
                // get information about detected objects
                var shapeChecker = new SimpleShapeChecker();

                var letters = new List<Letter>();

                int circleCount = 0;
                foreach (
                    var blob in
                        blobs.ToArray()
                            .OrderBy(b => b.Rectangle.Top)
                            .ThenBy(b => b.Rectangle.Left)
                            .ThenByDescending(b => b.Area))
                {

                    List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);

                    AForge.Point center;
                    float radius;

                    if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                    {

                        //Todo: filter on the largest radius * 90% to deal with resolutions
                        if (radius < 40)
                            continue;

                        blobCounter.ExtractBlobsImage(bitmap, blob, false);
                        var letter = blob.Image.ToManagedImage(true);
                        var resizeFilter = new ResizeBilinear(150, 150);
                        letter = resizeFilter.Apply(letter);

                        var bwBitmap = new Bitmap(75, 75, PixelFormat.Format32bppArgb);

                        for (int y = 40; y < 115; y++)
                        {
                            for (int x = 40; x < 115; x++)
                            {
                                var color = letter.GetPixel(x, y);
                                if (color.Name == "ff000000")
                                {
                                    bwBitmap.SetPixel(x - 40, y - 40, Color.Black);
                                }
                                else
                                {
                                    bwBitmap.SetPixel(x - 40, y - 40, Color.White);
                                }
                            }
                        }

                       letters.Add(new Letter
                       {
                           L = TrainingData.GetBestGuess(bwBitmap),
                           X = center.X,
                           Y = center.Y,
                           Radius = radius
                       });
                    }
                }

                var minX = letters.Min(c => c.X);
                var maxX = letters.Max(c => c.X);

                var minY = letters.Min(c => c.Y);
                var maxY = letters.Max(c => c.Y);

                var smallestRadius = letters.Min(c => c.Radius);

                var numberOfItemsPerRow = (int)((maxX - minX)/ smallestRadius / 2);
                var numberOfItemsPerCol = (int)((maxY - minY) / smallestRadius / 2);

                var spaceBetweenPointsX = (maxX - minX)/numberOfItemsPerRow;
                var spaceBetweenPointsY = (maxY - minY) / numberOfItemsPerCol;

                var varianceDelta = smallestRadius*.05f; //allow 5% pixel float

                var puzzle = new StringBuilder();
                for (var y = minY; y <= maxY; y += spaceBetweenPointsY)
                {

                    for (var x = minX; x <= maxX; x += spaceBetweenPointsX)
                    {
                        var item = letters.FirstOrDefault(c => c.X > x - varianceDelta && c.X < x + varianceDelta
                                                               && c.Y > y - varianceDelta && c.Y < y + varianceDelta);

                        if (item != null)
                            puzzle.Append(item.L);
                        else
                            puzzle.Append("_");
                    }

                    puzzle.AppendLine();
                }

                Data = puzzle.ToString();

            }

            var solutions = SolvePuzzle(Data, Smallest, Largest);
            return View(new PuzzleModel
            {
                Data = Data,
                Largest = Largest,
                Smallest = Smallest,
                Solutions = solutions,
                Base64Image = base64Image
            });
        }
예제 #23
0
파일: Form1.cs 프로젝트: juanlurie/Tools
        public Form1()
        {
            InitializeComponent();

            Bitmap image = new Bitmap(@"C:\Images\bitmap.bmp");

            Invert filter = new Invert();

            // apply the filter
            filter.ApplyInPlace(image);

            var shapeChecker = new SimpleShapeChecker();

            BlobCounter blobCounter = new BlobCounter();
            // process input image

            blobCounter.ProcessImage(image);
            // get information about detected objects
            Blob[] blobs = blobCounter.GetObjectsInformation();

            var squares = 0;

            Graphics g = Graphics.FromImage(image);
            Pen bluePen = new Pen(Color.Yellow, 2);
            Pen redpen = new Pen(Color.Red, 2);

            var quads = blobs.Where(x => shapeChecker.IsQuadrilateral(blobCounter.GetBlobsEdgePoints(x)));
            var largest = quads.OrderByDescending(x => x.Area).First();

            List<IntPoint> largestedgePoints = blobCounter.GetBlobsEdgePoints(largest);
                List<IntPoint> largestcorners;
            shapeChecker.IsQuadrilateral(largestedgePoints, out largestcorners);

            var largestpoints = largestcorners.Select(x => new PointF(x.X, x.Y)).ToArray();
            //g.DrawPolygon(redpen, largestpoints);

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

                Point center;
                float radius;

                if(blobs[i].Area < 150)
                    continue;

                if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                {
                    var a = corners.Select(x => new IntPoint(x.X, x.Y)).ToList();

                    var shape = shapeChecker.CheckPolygonSubType(a);

                    if (shape == PolygonSubType.Square || shape == PolygonSubType.Rectangle)
                    {
                        if (corners.Min(x => x.Y) < largestcorners.Min(x => x.Y) ||
                            corners.Min(x => x.Y) > largestcorners.Max(x => x.Y))
                        {
                            var points = corners.Select(x => new PointF(x.X, x.Y)).ToArray();
                            g.DrawPolygon(bluePen, points);
                        }
                    }
                }
                else if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    //g.DrawEllipse(bluePen,
                    //        (int)(center.X - radius),
                    //        (int)(center.Y - radius),
                    //        (int)(radius * 2),
                    //        (int)(radius * 2));
                }
            }
            pictureBox1.Image = image;

            bluePen.Dispose();
            g.Dispose();
        }
예제 #24
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;
        }
예제 #25
0
        // todo: implement this
        //public IBlobsFilter BlobsFilter
        /// <summary>
        /// uses AForge to detect square (or rectangular, if tile is obscured) tiles in the image
        /// </summary>
        /// <param name="img"></param>
        public void DetectBlobsInImage(Bitmap img)
        {
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.ProcessImage(img);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            Graphics g = Graphics.FromImage(img);
            System.Drawing.Pen bluePen = new System.Drawing.Pen(System.Drawing.Color.Blue, 10);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                try
                {
                    List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
                    List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints);

                    SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
                    PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners);
                    if (subType == PolygonSubType.Square)
                    {
                        g.DrawPolygon(bluePen, PointsListToArray(corners));
                    }
                }
                catch (Exception) { }
            }

            bluePen.Dispose();
            g.Dispose();
        }
예제 #26
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;
        }
예제 #27
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);
        }
예제 #28
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);
        }
예제 #29
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;
        }
예제 #30
-1
        // 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 );

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

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

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

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

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

            // 4 - check shape of each blob
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker( );

            log.AddMessage( "Found coins: " );
            int count = 0;

            // create graphics object for drawing on image
            Graphics g = Graphics.FromImage( image );
            Pen pen = new Pen( Color.Red, 3 );

            foreach ( Blob blob in blobs )
            {
                List<IntPoint> edgePoint = blobCounter.GetBlobsEdgePoints( blob );

                // check if shape looks like a circle
                DoublePoint center;
                double radius;

                if ( shapeChecker.IsCircle( edgePoint, out center, out radius ) )
                {
                    count++;

                    log.AddMessage( string.Format( "  {0}: center = ({1}, {2}), radius = {3}",
                        count, center.X, center.Y, radius ) );

                    // highlight coin
                    g.DrawEllipse( pen, (int) ( center.X - radius ), (int) ( center.Y - radius ),
                        (int) ( radius * 2 ), (int) ( radius * 2 ) );
                }
            }

            g.Dispose( );
            pen.Dispose( );

            log.AddMessage( "Total coins: " + count);
            log.AddImage( "Coins", image );
        }