Ask Your Question

Revision history [back]

Real distance between points with emgu.cv

Hi everybody,

I'm newbe using opencv. I usually work with C# and I have installed Emgu.cv to use opencv (2.3.1) with C# on Visual Studio 2010. I have started to find shapes like rectangles using the next code:

static public Image< Bgr, Byte > getShapes( WriteableBitmap aWriteableBitmap )
        {
            BitmapEncoder anEncoder = new PngBitmapEncoder( );
            anEncoder.Frames.Add( BitmapFrame.Create( aWriteableBitmap ) );
            MemoryStream aMemoryStream = new MemoryStream( );
            anEncoder.Save( aMemoryStream );
            Bitmap aBitmap = new Bitmap( aMemoryStream );
            bool aFlagRectangle = false;

            Image< Bgr, Byte >   aSourceImage = new Image< Bgr, Byte >( aBitmap );
            Image< Gray, Byte >  aGrayImage   = aSourceImage.Convert< Gray, Byte >( ).PyrDown( ).PyrUp( );

            Gray aCannyThreshold              = new Gray( 180 );
            Gray aCannyThresholdLinking       = new Gray( 120 );
            Gray aMinThreshold                = new Gray( 50 );
            Gray aMaxThreshold                = new Gray( 255 );

            Image< Gray, Byte > aCannyImages  = aGrayImage.Convert< Gray, Byte >( ).Canny( aCannyThreshold, aCannyThresholdLinking ).ThresholdBinary( aMinThreshold, aMaxThreshold );

            aCannyImages._Dilate(2);

            LineSegment2D[ ] aLines           = aCannyImages.HoughLinesBinary( 1,               // Distance resolution in pixel-related units
                                                                               Math.PI / 45.0,  // Angle resolution measured in radians.
                                                                               10,              // Threshold
                                                                               20,              // Min Line width
                                                                               30               // Gap between lines
                                                                               )[0];            // Get the lines from the first channel

            List< MCvBox2D > aBoxList         = new List< MCvBox2D >( );

            using ( MemStorage aStorage = new MemStorage( ) )

            for ( Contour< System.Drawing.Point > aContours = aCannyImages.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_TC89_KCOS , Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, aStorage );
                    aContours != null;
                    aContours = aContours.HNext )
            {
                Contour< System.Drawing.Point > aCurrentContour = aContours.ApproxPoly( aContours.Perimeter * 0.05, aStorage );

                if ( aContours.Area > 75 ) // Only consider contours with area greater than 50
                {
                    if ( aCurrentContour.Total == 4 ) // The contour has 4 vertices.
                    {
                        bool aIsRectangle             = true;
                        System.Drawing.Point[ ] aPts  = aCurrentContour.ToArray( );
                        LineSegment2D[ ] anEdges      = Emgu.CV.PointCollection.PolyLine( aPts, true );

                        for ( int i = 0; i < anEdges.Length; i++ )
                        {
                            double anAngle = Math.Abs( anEdges[ ( i + 1 ) % anEdges.Length ].GetExteriorAngleDegree( anEdges[ i ] ) );

                            if ( anAngle < 60 || anAngle > 100 )
                            {
                                aIsRectangle    = false;
                                break;
                            }
                        }

                        if ( aIsRectangle && aBoxList.Capacity == 0 )
                        {
                            aBoxList.Add( aCurrentContour.GetMinAreaRect( ) );

                            aFlagRectangle = true;
                        }
                    }
                }
            }

            Image< Bgr, Byte > triangleRectangleImage = aCannyImages.Convert< Bgr, Byte >( );

            foreach ( MCvBox2D aBox in aBoxList )
            {
                triangleRectangleImage.Draw( aBox, new Bgr( System.Drawing.Color.Orange ), 2 );
            }

            return triangleRectangleImage;
        }
    }

During debugging, I have seen that I get an array with 4 points with X and Y coordinates (aPts). Then, my question is, It's possible to get the real distance between the points to know what are the real measures of the object). The distance from camera to object is 1 m. I attach a picture of the object captured. C:\fakepath\capture_emgucv.png

Thanks,

Real distance between points with emgu.cv

Hi everybody,

I'm newbe new using opencv. I usually work with C# and I have installed Emgu.cv to use opencv (2.3.1) with C# on Visual Studio 2010. I have started to find shapes like rectangles using the next code:

static public Image< Bgr, Byte > getShapes( WriteableBitmap aWriteableBitmap )
        {
            BitmapEncoder anEncoder = new PngBitmapEncoder( );
            anEncoder.Frames.Add( BitmapFrame.Create( aWriteableBitmap ) );
            MemoryStream aMemoryStream = new MemoryStream( );
            anEncoder.Save( aMemoryStream );
            Bitmap aBitmap = new Bitmap( aMemoryStream );
            bool aFlagRectangle = false;

            Image< Bgr, Byte >   aSourceImage = new Image< Bgr, Byte >( aBitmap );
            Image< Gray, Byte >  aGrayImage   = aSourceImage.Convert< Gray, Byte >( ).PyrDown( ).PyrUp( );

            Gray aCannyThreshold              = new Gray( 180 );
            Gray aCannyThresholdLinking       = new Gray( 120 );
            Gray aMinThreshold                = new Gray( 50 );
            Gray aMaxThreshold                = new Gray( 255 );

            Image< Gray, Byte > aCannyImages  = aGrayImage.Convert< Gray, Byte >( ).Canny( aCannyThreshold, aCannyThresholdLinking ).ThresholdBinary( aMinThreshold, aMaxThreshold );

            aCannyImages._Dilate(2);

            LineSegment2D[ ] aLines           = aCannyImages.HoughLinesBinary( 1,               // Distance resolution in pixel-related units
                                                                               Math.PI / 45.0,  // Angle resolution measured in radians.
                                                                               10,              // Threshold
                                                                               20,              // Min Line width
                                                                               30               // Gap between lines
                                                                               )[0];            // Get the lines from the first channel

            List< MCvBox2D > aBoxList         = new List< MCvBox2D >( );

            using ( MemStorage aStorage = new MemStorage( ) )

            for ( Contour< System.Drawing.Point > aContours = aCannyImages.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_TC89_KCOS , Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, aStorage );
                    aContours != null;
                    aContours = aContours.HNext )
            {
                Contour< System.Drawing.Point > aCurrentContour = aContours.ApproxPoly( aContours.Perimeter * 0.05, aStorage );

                if ( aContours.Area > 75 ) // Only consider contours with area greater than 50
                {
                    if ( aCurrentContour.Total == 4 ) // The contour has 4 vertices.
                    {
                        bool aIsRectangle             = true;
                        System.Drawing.Point[ ] aPts  = aCurrentContour.ToArray( );
                        LineSegment2D[ ] anEdges      = Emgu.CV.PointCollection.PolyLine( aPts, true );

                        for ( int i = 0; i < anEdges.Length; i++ )
                        {
                            double anAngle = Math.Abs( anEdges[ ( i + 1 ) % anEdges.Length ].GetExteriorAngleDegree( anEdges[ i ] ) );

                            if ( anAngle < 60 || anAngle > 100 )
                            {
                                aIsRectangle    = false;
                                break;
                            }
                        }

                        if ( aIsRectangle && aBoxList.Capacity == 0 )
                        {
                            aBoxList.Add( aCurrentContour.GetMinAreaRect( ) );

                            aFlagRectangle = true;
                        }
                    }
                }
            }

            Image< Bgr, Byte > triangleRectangleImage = aCannyImages.Convert< Bgr, Byte >( );

            foreach ( MCvBox2D aBox in aBoxList )
            {
                triangleRectangleImage.Draw( aBox, new Bgr( System.Drawing.Color.Orange ), 2 );
            }

            return triangleRectangleImage;
        }
    }

During debugging, I have seen that I get an array with 4 points with X and Y coordinates (aPts). Then, my question is, It's possible to get the real distance between the points to know what are the real measures of the object). The distance from camera to object is 1 m. I attach a picture of the object captured. C:\fakepath\capture_emgucv.png

Thanks,