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

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

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

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

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

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

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

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

        }
Example #2
0
        // 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
                AForge.Point center;
                float        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);
        }
Example #3
0
        // 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
            Bitmap grayImage = Grayscale.CommonAlgorithms.BT709.Apply(image);

            log.AddImage("Grayscale", grayImage);

            // 2 - Edge detection
            DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector( );
            Bitmap edges = edgeDetector.Apply(grayImage);

            log.AddImage("Edges", edges);

            // 3 - Threshold edges
            Threshold thresholdFilter = new Threshold(40);

            thresholdFilter.ApplyInPlace(edges);
            log.AddImage("Thresholded Edges", edges);

            // 4 - Blob Counter
            BlobCounter blobCounter = new BlobCounter( );

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

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

            // create unmanaged copy of source image, so we could draw on it
            UnmanagedImage imageData = UnmanagedImage.FromManagedImage(image);

            // Get unmanaged copy of grayscale image, so we could access it's pixel values
            UnmanagedImage grayUI = UnmanagedImage.FromManagedImage(grayImage);

            // list of found dark/black quadrilaterals surrounded by white area
            List <List <IntPoint> > foundObjects = new List <List <IntPoint> >( );
            // shape checker for checking quadrilaterals
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker( );

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

                // does it look like a quadrilateral ?
                if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                {
                    // do some more checks to filter so unacceptable shapes
                    // if ( CheckIfShapeIsAcceptable( corners ) )
                    {
                        log.AddMessage("Blob size: " + blobs[i].Rectangle.Width + " x " + blobs[i].Rectangle.Height);

                        // 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 = this.CalculateAverageEdgesBrightnessDifference(
                            leftEdgePoints, rightEdgePoints, grayUI);

                        log.AddMessage("Avg Diff: " + diff);

                        // check average difference, which tells how much outside is lighter than inside on the average
                        if (diff > 20)
                        {
                            Drawing.Polygon(imageData, corners, Color.FromArgb(255, 255, 0, 0));
                            // add the object to the list of interesting objects for further processing
                            foundObjects.Add(corners);
                        }
                    }
                }
            }


            log.AddImage("Potential glyps", imageData.ToManagedImage());

            int counter = 1;

            // further processing of each potential glyph
            foreach (List <IntPoint> corners in foundObjects)
            {
                log.AddMessage("Glyph #" + counter);

                log.AddMessage(string.Format("Corners: ({0}), ({1}), ({2}), ({3})",
                                             corners[0], corners[1], corners[2], corners[3]));

                // 6 - do quadrilateral transformation
                QuadrilateralTransformation quadrilateralTransformation =
                    new QuadrilateralTransformation(corners, 250, 250);

                Bitmap transformed = quadrilateralTransformation.Apply(grayImage);

                log.AddImage("Transformed #" + counter, transformed);

                // 7 - otsu thresholding
                OtsuThreshold otsuThresholdFilter = new OtsuThreshold( );
                Bitmap        transformedOtsu     = otsuThresholdFilter.Apply(transformed);
                log.AddImage("Transformed Otsu #" + counter, transformedOtsu);

                int glyphSize = 5;
                SquareBinaryGlyphRecognizer gr = new SquareBinaryGlyphRecognizer(glyphSize);

                bool[,] glyphValues = gr.Recognize(ref transformedOtsu,
                                                   new Rectangle(0, 0, 250, 250));

                log.AddImage("Glyph lines #" + counter, transformedOtsu);

                // output recognize glyph to log
                log.AddMessage(string.Format("glyph: {0:F2}%", gr.confidence * 100));
                for (int i = 0; i < glyphSize; i++)
                {
                    StringBuilder sb = new StringBuilder("   ");

                    for (int j = 0; j < glyphSize; j++)
                    {
                        sb.Append((glyphValues[i, j]) ? "1 " : "0 ");
                    }

                    log.AddMessage(sb.ToString( ));
                }

                counter++;
            }
        }
Example #4
0
        // 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
            Bitmap grayImage = Grayscale.CommonAlgorithms.BT709.Apply( image );
            log.AddImage( "Grayscale", grayImage );

            // 2 - Edge detection
            DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector( ); 
            Bitmap edges = edgeDetector.Apply( grayImage );
            log.AddImage( "Edges", edges );

            // 3 - Threshold edges
            Threshold thresholdFilter = new Threshold( 40 ); 
            thresholdFilter.ApplyInPlace( edges );
            log.AddImage( "Thresholded Edges", edges );

            // 4 - Blob Counter
            BlobCounter blobCounter = new BlobCounter( );
            blobCounter.MinHeight = 32;
            blobCounter.MinWidth  = 32;
            blobCounter.FilterBlobs  = true;
            blobCounter.ObjectsOrder = ObjectsOrder.Size;

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

            // create copy of source image, so we could draw on it
            Bitmap imageCopy = AForge.Imaging.Image.Clone( image );

            BitmapData imageData = imageCopy.LockBits( new Rectangle( 0, 0, image.Width, image.Height ),
                ImageLockMode.ReadWrite, imageCopy.PixelFormat );

            // lock grayscale image, so we could access it's pixel values
            BitmapData grayData = grayImage.LockBits( new Rectangle( 0, 0, image.Width, image.Height ),
                ImageLockMode.ReadOnly, grayImage.PixelFormat );
            UnmanagedImage grayUI = new UnmanagedImage( grayData );

            // list of found dark/black quadrilaterals surrounded by white area
            List<List<IntPoint>> foundObjects = new List<List<IntPoint>>( );
            // shape checker for checking quadrilaterals
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker( );

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

                // does it look like a quadrilateral ?
                if ( shapeChecker.IsQuadrilateral( edgePoints, out corners ) )
                {
                    // do some more checks to filter so unacceptable shapes
                    // if ( CheckIfShapeIsAcceptable( corners ) )
                    {
                        log.AddMessage( "Blob size: " + blobs[i].Rectangle.Width + " x " + blobs[i].Rectangle.Height );

                        // 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, grayUI );

                        log.AddMessage( "Avg Diff: " + diff );

                        // check average difference, which tells how much outside is lighter than inside on the average
                        if ( diff > 20 )
                        {
                            Drawing.Polygon( imageData, corners, Color.Red );
                            // add the object to the list of interesting objects for further processing
                            foundObjects.Add( corners );
                        }
                    }
                }
            }

            imageCopy.UnlockBits( imageData );
            grayImage.UnlockBits( grayData );

            log.AddImage( "Potential glyps", imageCopy );

            int counter = 1;

            // further processing of each potential glyph
            foreach ( List<IntPoint> corners in foundObjects )
            {
                log.AddMessage( "Glyph #" + counter );
                
                log.AddMessage( string.Format( "Corners: ({0}), ({1}), ({2}), ({3})",
                    corners[0], corners[1], corners[2], corners[3] ) );

                // 6 - do quadrilateral transformation
                QuadrilateralTransformation quadrilateralTransformation =
                    new QuadrilateralTransformation( corners, 250, 250 );

                Bitmap transformed = quadrilateralTransformation.Apply( grayImage );

                log.AddImage( "Transformed #" + counter, transformed );

                // 7 - otsu thresholding
                OtsuThreshold otsuThresholdFilter = new OtsuThreshold( ); 
                Bitmap transformedOtsu = otsuThresholdFilter.Apply( transformed );
                log.AddImage( "Transformed Otsu #" + counter, transformedOtsu );

                int glyphSize = 5;
                SquareBinaryGlyphRecognizer gr = new SquareBinaryGlyphRecognizer( glyphSize );

                bool[,] glyphValues = gr.Recognize( transformedOtsu,
                    new Rectangle( 0, 0, 250, 250 ) );

                log.AddImage( "Glyph lines #" + counter, transformedOtsu );

                // output recognize glyph to log
                log.AddMessage( string.Format( "glyph: {0:F2}%", gr.confidence * 100 ) );
                for ( int i = 0; i < glyphSize; i++ )
                {
                    StringBuilder sb = new StringBuilder( "   " );

                    for ( int j = 0; j < glyphSize; j++ )
                    {
                        sb.Append( ( glyphValues[i, j] ) ? "1 " : "0 " );
                    }

                    log.AddMessage( sb.ToString( ) );
                }

                counter++;
            }
        }
Example #5
-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 );
        }