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
文章標籤
全站熱搜