只需在图像中使用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
如果轮廓 i 没有下一个、上一个、父级或嵌套轮廓,则 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
}
结果: