close

 

Bounding Box, Circle Detection, Triangle Detection.

 


Input : iplOri as gray image ( 1 chennel )

Output : iplObj as color image ( 3 chennel )

 

 

#1. Bounding Box

 
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
//---------------------------------------------------------
cvFindContours( iplOri , storage , & contour , sizeof(CvContour) , CV_RETR_EXTERNAL , CV_CHAIN_APPROX_SIMPLE , cvPoint(0,0) );
//---------------------------------------------------------
for(;contour!=0;contour=contour->h_next)
{
	CvRect AndRect = cvBoundingRect( contour , 0 );
//---------------------------------------------------------
	int area = AndRect.width * AndRect.height;
	int count = fabs( cvContourArea( contour , CV_WHOLE_SEQ ) );
	float ratio = (float) AndRect.width / AndRect.height;
//---------------------------------------------------------
//-- SIZE less than INT_MIN_SIZE or more than INT_MAX_SIZE - OUT
//---------------------------------------------------------
	if( area < INT_MIN_SIZE * INT_MIN_SIZE || area > INT_MAX_SIZE * INT_MAX_SIZE ) continue;
//---------------------------------------------------------
//-- WIDTH:HEIGHT more than INT_WH_RATIO - OUT
//---------------------------------------------------------
	if( ratio < (float) INT_WH_RATIO/10 || ratio > (float) 10/INT_WH_RATIO ) continue;
//---------------------------------------------------------
//-- DENSITY less than INT_AREA_RATIO - OUT
//---------------------------------------------------------
	if( (float) count/area < (float) INT_AREA_RATIO/100 ) continue;
//---------------------------------------------------------
	CvPoint RECT1, RECT2;
	RECT1.x = AndRect.x;
	RECT1.y = AndRect.y;
	RECT2.x = AndRect.x + AndRect.width;
	RECT2.y = AndRect.y + AndRect.height;
//---------------------------------------------------------
	cvRectangle( iplObj , RECT1, RECT2, CV_RGB(255,0,0) , 2 , 8 , 0 );
}
 

 

#2. Circle Detection

 
CvMemStorage* storageCircle = cvCreateMemStorage(0);
//---------------------------------------------------------
cvSmooth( iplOri , iplOri , CV_GAUSSIAN, 9, 9 ); 
//---------------------------------------------------------
double dp=2;
double min_dist=10;
int min_radius=5;
int max_radius=150; 
CvSeq* circles = cvHoughCircles( iplOri , storageCircle, CV_HOUGH_GRADIENT , dp , min_dist, min_radius , max_radius );
//---------------------------------------------------------
for( int i = 0; i < circles->total; i++ )
{
	 float* p = (float*) cvGetSeqElem( circles , i );
	 cvCircle( iplObj , cvPoint( cvRound(p[0]) , cvRound(p[1]) ) , cvRound(p[2]) , CV_RGB(255,255,0) , 3 , 8 , 0 );
}
 

 

#3. Triangle Detection

 
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
//---------------------------------------------------------
CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );
CvSeqReader reader;
//---------------------------------------------------------
cvSmooth( iplOri , iplOri , CV_GAUSSIAN, 9, 9 ); 
cvFindContours( iplOri , storage , & contour , sizeof(CvContour) , CV_RETR_EXTERNAL , CV_CHAIN_APPROX_SIMPLE , cvPoint(0,0) );
//---------------------------------------------------------
for(;contour!=0;contour=contour->h_next)
{
	CvRect AndRect = cvBoundingRect( contour , 0 );
//---------------------------------------------------------
	int area = AndRect.width * AndRect.height;
	int count = fabs( cvContourArea( contour , CV_WHOLE_SEQ ) );
	float ratio = (float) AndRect.width / AndRect.height;
//---------------------------------------------------------
//-- SIZE less than INT_MIN_SIZE or more than INT_MAX_SIZE - OUT
//---------------------------------------------------------
	if( area < INT_MIN_SIZE * INT_MIN_SIZE || area > INT_MAX_SIZE * INT_MAX_SIZE ) continue;
//---------------------------------------------------------
//-- WIDTH:HEIGHT more than INT_WH_RATIO - OUT
//---------------------------------------------------------
	if( ratio < (float) INT_WH_RATIO/10 || ratio > (float) 10/INT_WH_RATIO ) continue;
//---------------------------------------------------------
	CvSeq* result = cvApproxPoly( contour , sizeof(CvContour) , storage , CV_POLY_APPROX_DP , cvContourPerimeter(contour)*0.2 , 0 );
//---------------------------------------------------------
	if( result->total == 3 )
	{
		for(int i=0;i<3;i++)
			cvSeqPush( squares, (CvPoint*)cvGetSeqElem( result, i ));
	//---------------------------------------------------------
		cvStartReadSeq( squares, &reader, 0 );
	//---------------------------------------------------------
		for(int i=0;i<squares->total;i+=3)
		{
			CvPoint pt[3], *rect = pt;
			int count = 3;
		//---------------------------------------------------------
			CV_READ_SEQ_ELEM( pt[0], reader );
			CV_READ_SEQ_ELEM( pt[1], reader );
			CV_READ_SEQ_ELEM( pt[2], reader );
		//---------------------------------------------------------
			CvPoint p1 = cvPoint( Math::Min( pt[0].x , Math::Min( pt[1].x , pt[2].x ) ) , Math::Min( pt[0].y , Math::Min( pt[1].y , pt[2].y ) ) );
			CvPoint p2 = cvPoint( Math::Max( pt[0].x , Math::Max( pt[1].x , pt[2].x ) ) , Math::Max( pt[0].y , Math::Max( pt[1].y , pt[2].y ) ) );
		//---------------------------------------------------------
			cvPolyLine( iplObj , &rect, &count, 1, 1, CV_RGB(0,255,0), 3, CV_AA, 0 );
		}
	}
}
 

 

Output

 

 - red : bounding box

 - green : triangle

 - yellow : circle

 

box, triangle  

circle  

 

 

arrow
arrow
    創作者介紹
    創作者 Cuby 56 的頭像
    Cuby 56

    Cuby56

    Cuby 56 發表在 痞客邦 留言(1) 人氣()