在 OpenCV 的 findContours() 中使用层次结构?

Posted

技术标签:

【中文标题】在 OpenCV 的 findContours() 中使用层次结构?【英文标题】:Using hierarchy in findContours () in OpenCV? 【发布时间】:2012-01-17 16:43:49 【问题描述】:

在寻找轮廓时,我使用了 CV_RETR_CCOMP 参数。这应该创建一个两级层次结构 - 第一级用于外部轮廓,第二级用于孔的边界。但是,我以前从未使用过层次结构,因此对此并不熟悉。

有人可以指导我如何仅访问孔的边界吗?我想忽略外部轮廓,只绘制孔边界。代码示例将不胜感激。我使用的是 C++ 接口而不是 C,所以请不要建议使用 C 函数(即使用 findContours () 而不是 cvFindContours ())。

【问题讨论】:

在 C++ 版本和 C 版本之间切换是微不足道的。仅供参考。 【参考方案1】:

findContours 返回的层次结构如下: hierarchy[idx][0,1,2,3]=next contour (same level), previous contour (same level), child contour, parent contour

CV_RETR_CCOMP,返回外部轮廓和孔的层次结构。 这意味着hierarchy[idx] 的元素 2 和 3 最多有一个不等于 -1:也就是说,每个元素要么没有父节点,要么没有子节点,或者有父节点但没有子节点,或者有子节点但没有父节点。

具有父元素但没有子元素的元素将成为孔的边界。

这意味着您基本上通过hierarchy[idx] 并使用hierarchy[idx][3]>-1 绘制任何东西。

类似的东西(在 Python 中工作,但尚未测试 C++。不过想法很好。):

findContours( image, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

if ( !contours.empty() && !hierarchy.empty() ) 

    // loop through the contours/hierarchy
    for ( int i=0; i<contours.size(); i++ ) 

        // look for hierarchy[i][3]!=-1, ie hole boundaries
        if ( hierarchy[i][3] != -1 ) 
            // random colour
            Scalar colour( (rand()&255), (rand()&255), (rand()&255) );
            drawContours( outImage, contours, i, colour );
        
    

【讨论】:

@Farhad 确保您进行了一些测试。层次结构可能不是您所期望的。我用你来自***.com/questions/8449378/finding-contours-in-opencv 的图像尝试了这个,图像框架是父母,外轮廓是孩子,内轮廓都不是。 @Farhad 抱歉,我的意思是图像框架是孩子,而圆圈的外轮廓是父母。 谢谢,我想我得想办法解决了。【参考方案2】:

AFAIK 使用 CV_RETR_CCOMP 时,所有孔都在同一水平面上。

int firstHoleIndex = hierarchy[0][2];
for (int i = firstHoleIndex; i >= 0 ; i = hierarchy[i][0])
// contours.at(i) is a hole. Do something with it.

【讨论】:

如果第一个轮廓没有孔,这将不起作用。

以上是关于在 OpenCV 的 findContours() 中使用层次结构?的主要内容,如果未能解决你的问题,请参考以下文章

findContours 在 opencv 中找不到轮廓

OpenCV findContours 函数问题

OpenCV findContours 堆栈溢出

OpenCV cv::findcontours *** 异常

opencv findContours函数

OpenCV 2.4.2 findContours(),如何只得到直线轮廓