2014-03-07 73 views
13

如何檢測和開放OpenCV中封閉的形狀。認識到開放和關閉形狀的OpenCV

enter image description here

這些都是簡單的樣品的形狀我想檢測。我使用findContoursapproxPolyDP檢測矩形,並檢查矢量之間的角度。

現在我想檢測打開的形狀,approxPolyDP功能已關閉形狀布爾設置爲true,還有isCounterConvex上返回的點檢查,再加上contourArea限制。

任何想法如何,我應該去檢測這些類型的圖像。

回答

21

在圖像只需使用findContours(),然後決定通過檢查傳遞給findContours()函數的層次輪廓是否關閉與否。從第二幅圖可以看出,沒有輪廓與第一幅圖像相比具有子輪廓,您將從可選輸出矢量的層級參數中獲取此數據,其中包含有關圖像拓撲的信息。它具有與輪廓數量一樣多的元素。

在這裏,我們將使用層次結構

vector<Vec4i> hierarchy 

其中對於第i輪廓

hierarchy[i][0] = next contour at the same hierarchical level 
hierarchy[i][1] = previous contour at the same hierarchical level 
hierarchy[i][2] = denotes its first child contour 
hierarchy[i][3] = denotes index of its parent contour 

如果輪廓我有沒有未來,以前,父母,或嵌套的輪廓,該hierarchy[i]的相應元素將爲負數。有關更多詳細信息,請參閱findContours()函數。

因此,通過檢查值hierarchy[i][2],您可以決定輪廓屬於關閉還是不關閉,也就是說,對於輪廓如果hierarchy[i][2] = -1沒有小孩,並且它屬於已打開。

還有一件事是,在findContours()函數,你應該使用CV_RETR_CCOMP其檢索所有的輪廓,並將它們組織成兩個層次結構。

這裏是C++代碼如何實現這一點。

Mat tmp,thr; 
    Mat src=imread("1.png",1); 
    cvtColor(src,tmp,CV_BGR2GRAY); 
    threshold(tmp,thr,200,255,THRESH_BINARY_INV); 

    vector< vector <Point> > contours; // Vector for storing contour 
    vector<Vec4i> hierarchy; 
    findContours(thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); 

    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) //Check if there is a child contour 
      rectangle(src,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10), Scalar(0,0,255),2,8,0); //Opened contour 
     else 
      rectangle(src,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 
    } 

結果:

enter image description here

0

答案取決於你的形象,更具體,很多輪廓是如何設定,是有其他的目的,噪聲等在簡單情況下在封閉輪廓內開始的單輪廓填充不會溢出整個圖像;如果從外面開始,它不會在中間。所以你會在這兩種情況下保留一些白色區域。

2

雖然對於所提出的問題正確,但@Haris有用的答案不應被視爲使用findContours()識別封閉輪廓的一般解決方案。

原因之一是填充物體沒有內部輪廓,因此會返回hierarchy[i][2] = -1,這意味着此測試本身會錯誤地將這些輪廓標記爲「打開」。

填充對象的輪廓在輪廓層次結構中應該沒有子對象或父對象,即處於頂層。因此,要檢測填充物體的閉合輪廓,至少需要額外的測試:if(hierarchy[i][2] < 0 && hierarchy[i][3] < 0)

我認爲@哈里斯的回答可能使這一點傾斜,但我認爲值得澄清的人,如我自己,誰在學習如何使用opencv。