找封閉區域 ─ findContours 函式應用
void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset=Point()); /* mode: CV_RETR_EXTERNAL:只取最外層的輪廓。 CV_RETR_LIST:取得所有輪廓,不建立階層(hierarchy)。 CV_RETR_CCOMP:取得所有輪廓,儲存成兩層的階層,首階層為物件外圍, 第二階層為內部空心部分的輪廓,如果更內部有其餘物件,包含於首階層。 //若要找封閉區域,需要用此mode來做contour間的階層 CV_RETR_TREE:取得所有輪廓,以全階層的方式儲存。 method: CV_CHAIN_APPROX_NONE:儲存所有輪廓點。 CV_CHAIN_APPROX_SIMPLE:對水平、垂直、對角線留下頭尾點,所以假如輪廓為一 矩形,只儲存對角的四個頂點。 */使用範例://部分取自opencv doc 範例
stackoverflow Recognize open and closed shapes opencv
void contour( Mat image, Mat closeArea ) { vector[int] contours; vector[vec4i] hierarchy; findContours( image, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE , Point(0, 0)); Mat drawing = Mat::zeros( image.size(), CV_8UC3 ); for( int i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); } for( int i = 0; i< contours.size(); i=hierarchy[i][0] ) // iterate through each contour. { Rect r= boundingRect(contours[i]); if( hierarchy[i][2] >= 0) { rectangle( closeArea,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,255,0),2,8,0); //closed contour } imshow( "Contours", closeArea ); imshow( "drawing", drawing ); } int main( int argc, char** argv ) { // Load source image and convert it to gray Mat src = imread( argv[1], 0 ); Mat thr = imread( argv[1], 1 ); imshow("src", src); threshold(src,src, 200, 255, THRESH_BINARY); imshow("binary", src); contour(src,thr); cvWaitKey(0); return(0); }
原圖
找到封閉區域
畫出輪廓
心得:
雖然用在這個例子上很好用, 但用在複雜的圖上,結果就有點糟糕了findContours在這張圖上,變得像是在找connected component的感覺了
思考了一陣子,發現其實是因為物件的邊緣並無完全封閉
所以造成無法用封閉區域來找到物件位置
沒有留言:
張貼留言