在轮廓/ OpenCV c ++中搜索轮廓

时间:2014-05-23 08:57:29

标签: c++ opencv

我正在尝试跟踪图片中的自定义圆形标记,我需要检查圆圈是否包含最少数量的其他圆/对象。我找到圈子的代码如下:

void findMarkerContours( int, void* )
{   
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
vector<Point> approx;

cv::Mat dst = src.clone();

cv::Mat src_gray;
cv::cvtColor(src, src_gray, CV_BGR2GRAY);
//Reduce noise with a 3x3 kernel
blur( src_gray, src_gray, Size(3,3));

//Convert to binary using canny
cv::Mat bw;
cv::Canny(src_gray, bw, thresh, 3*thresh, 3);

imshow("bw", bw);


findContours(bw.clone(), contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

Mat drawing = Mat::zeros( bw.size(), CV_8UC3 );

for (int i = 0; i < contours.size(); i++)
{
    Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    // contour
    drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );

    //Approximate the contour with accuracy proportional to contour perimeter
    cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true) *0.02, true);

    //Skip small or non-convex objects
    if(fabs(cv::contourArea(contours[i])) < 100 || !cv::isContourConvex(approx))
        continue;
    if (approx.size() >= 8) //More than 6-8 vertices means its likely a circle
    {
            drawContours( dst, contours, i, Scalar(0,255,0), 2, 8);
    }


    imshow("Hopefully we should have circles! Yay!", dst);

}

namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );

}

正如您所看到的,检测圈子的代码效果非常好:

但现在我需要过滤掉我不想要的标记。我的标记是最底层的。因此,一旦我找到了一个圆形轮廓,我想检查第一个圆圈区域内是否存在其他圆形轮廓,最后检查最小圆圈的颜色。

如果(圆圈包含3个以上的小圆圈||最小圆圈是[颜色]),我可以采用什么方法来说明 - &gt;做什么?

2 个答案:

答案 0 :(得分:3)

查看documentation

findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point())

您会看到有一个可选的hierarchy输出向量,这对您的问题应该很方便。

  

层次结构 - 可选输出向量,包含有关图像拓扑的信息。它具有与轮廓数量一样多的元素。   对于每个第i个轮廓轮廓[i],元素层次[i] [0],   hiearchy i,hiearchy i和hiearchy i设置为   基于0的指数在下一轮和前一轮的轮廓中   相同的层次级别,第一个子轮廓和父级   轮廓,分别。如果轮廓i没有下一个,   previous,parent或嵌套轮廓,相应的元素   等级[i]将是否定的。

使用findCountours致电CV_RETR_TREE时,您将获得找到的每个轮廓的完整层次结构。

doc很好地解释了hierarchy格式。

答案 1 :(得分:0)

您已在搜索特定尺寸的圈子

//Skip small or non-convex objects
if(fabs(cv::contourArea(contours[i])) < 100 || !cv::isContourConvex(approx))
    continue;

所以你可以用它来寻找比你得到的更小的圆圈,而不是寻找&lt; 100寻找contours.size

我想颜色也一样......