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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8461612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:36:43  来源:igfitidea点击:

Using hierarchy in findContours () in OpenCV?

c++imagelistimage-processingopencv

提问by fdh

When finding contours, I used the CV_RETR_CCOMP argument. This is supposed to create a two level hierarchy - the the first level are for outer contours, the second level are for boundaries of the holes. However, I have never used a hierarchy before so I am not familiar with this.

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

Could someone instruct my on how to access the boundaries of the holes only? I want to disregard the outer contours and only draw the hole boundaries. Code examples will be appreciated. I am using the C++ interface not the C, so please don't suggest C functions (i.e. use findContours () instead of cvFindContours ()).

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

回答by mathematical.coffee

The hierarchy returned by findContourshas the following form: hierarchy[idx][{0,1,2,3}]={next contour (same level), previous contour (same level), child contour, parent contour}

返回的层次结构findContours具有以下形式: hierarchy[idx][{0,1,2,3}]={next contour (same level), previous contour (same level), child contour, parent contour}

CV_RETR_CCOMP, returns a hierarchy of outer contours and holes. This means elements 2 and 3 of hierarchy[idx]have at most one of these not equal to -1: that is, each element has either no parent or child, or a parent but no child, or a child but no parent.

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

An element with a parent but no child would be a boundary of a hole.

有父元素但没有子元素的元素将是孔的边界。

That means you basically go through hierarchy[idx]and draw anything with hierarchy[idx][3]>-1.

这意味着你基本上经历hierarchy[idx]和画任何东西hierarchy[idx][3]>-1

Something like (works in Python, but haven't tested the C++. Idea is fine though.):

类似的东西(在 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 );
        }
    }
}

回答by Shmuel Fine

AFAIK when using CV_RETR_CCOMP, all the holes are on the same level.

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.