从轮廓中提取最外面的轮廓

时间:2016-08-01 11:51:05

标签: c++ opencv computer-vision

我需要检索几个轮廓的最外轮廓,可能以顺时针或逆时针顺序存储轮廓坐标。根据我的阅读,这种结果可以通过使用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());
}

有没有办法避免分割并删除孔的轮廓?

1 个答案:

答案 0 :(得分:0)

OpenCV有一个名为cv2.contourArea()的函数,它允许您计算输入轮廓的面积。如果您有多个轮廓,请使用此功能查找所有轮廓的区域并删除除最大轮廓之外的所有轮廓(一个区域最大,因为大轮廓内的轮廓不会有更大的区域)。之后,您将只剩下最大的外轮廓。