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,