如何在opencv中检测打开和关闭的形状。

这些是我要检测的简单样本形状。我已经使用findContoursapproxPolyDP检测到矩形,而不是检查 vector 之间的角度。

现在,我想检测开放形状,approxPolyDP函数将封闭形状的bool设置为true,并且还对返回点上的isCounterConvex进行了检查,并附加了contourArea限制。

任何想法我应该如何继续检测此类图像。

最佳答案

只需在图像中使用findContours(),然后通过检查传递给findContours()函数的层次结构来确定轮廓是否闭合。从第二张图中可以清楚地看到,与第一张图像相比,没有轮廓具有子轮廓,您将从分层参数(该数据是可选的输出 vector )中获取此数据,其中包含有关图像拓扑的信息。它具有与轮廓数量一样多的元素。

在这里,我们将层次结构用作

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
    }

结果:

10-04 13:59