2016-08-01 279 views
2

我需要檢索多個輪廓的最外輪廓,可能以順時針或逆時針順序存儲輪廓座標。從我讀過的,這種結果可以通過使用OpenCV的Canny + findContours歸檔。不幸的是,我必須詳細說明的大部分輪廓都是鋸齒狀的邊緣或孔,因此「標準程序」無法正常工作。舉例來說,如果我的形象是相當簡單的,無孔,結果是完全一樣的,我希望它(只是最外面的輪廓,並下令座標): Cup example從輪廓中提取最外輪廓

在有孔的照片時,我得到一個分段的最外面的輪廓(不同的顏色,見附圖),它仍然顯示最終圖像中的內孔。鋸齒邊緣我得到最壞的結果。顯示孔並且輪廓高度分段(Cat)。 Holes and jagged edges

代碼:

//add a small padding. Otherwise, in case of images where the border is partially cut out it won't be considered as a "closed" contour 
int topbottom = (int) (0.05*image.rows); 
int rightleft = (int) (0.05*image.cols); 
copyMakeBorder(image, image, topbottom, topbottom, rightleft, rightleft, BORDER_CONSTANT); 

//consider only alpha channel to create a silhouette 
Mat silhouette; 
vector<Mat> ch; 
split(image, ch); 

Canny(ch[3], silhouette, 100, 200); 

vector<vector<Point>> contours; 
vector<Vec4i> hierarchy; 

//find only the external contour 
findContours(silhouette, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

RNG rng(12345); 
Mat drawing = Mat::zeros(silhouette.size(), CV_8UC3); 
for(int i = 0; i < contours.size(); i++) 
{ 
    Scalar colour = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255)); 
    drawContours(drawing, contours, i, colour, 1, 8, hierarchy, 0, Point()); 
} 

有沒有辦法避免分割和去除孔的輪廓?

+3

你可以只發布你想要得到輪廓的圖像,而不需要額外的輪廓結果圖像。 –

+0

當然!這些是其中的一些 [第一樣品圖片(牀)](http://labelmaterial.s3.amazonaws.com/shapes/2KGnQ5RjIoXZXmoXr723dXz.png) [第二樣品圖片(貓)](http://labelmaterial.s3 .amazonaws.com/shapes/2NXvn0zPaDGXLIoQJ9LuyVT.png) – Izzy88

+0

您已經獲得了良好的閾值圖像(第2張圖像爲空洞和鋸齒狀邊緣)。現在只需從所有輪廓中找出最大輪廓並繪製它即可。您只會獲得一個外側輪廓想。 –

回答

0

OpenCV有一個叫cv2.contourArea()的功能,它可以讓你計算輸入輪廓的面積。如果您有多個輪廓,請使用此功能查找所有輪廓的區域,並刪除除最大輪廓以外的所有區域(其中一個輪廓最大,因爲大輪廓內的輪廓不會有較大的區域)。之後,您將只剩下最大的外部輪廓。