【问题标题】:OpenCV findContour method gives back "doubled" contourOpenCV findContour 方法返回“双倍”轮廓
【发布时间】:2015-08-20 21:01:13
【问题描述】:

我有一些非常简单的图像,我想从中提取最长的轮廓。

示例图片如下所示:

我正在使用来自 OpenCV 教程页面的确切 same sample code。有一点不同,我将阈值设置为一个固定数字,即 100。

主线是这个:

cv::findContours(cannyOutput, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));

调用上述函数后,我遍历找到的 contours 并检查哪个是最长的,然后我保存最长的那个。在最长的情况下,我的意思是哪一个得分最高。

在某些情况下,如上面的示例图像中,最长的轮廓会加倍。为了更容易理解,我在“加倍”下的意思是找到的轮廓的可视化图像:

所以我试图通过尝试理解OpenCV docs of findContour来弄清楚为什么会发生这种情况,但我仍然无法理解真正的原因。

我设法实现的目标是,如果我从 CV_RETR_TREE 更改为 CV_RETR_EXTERNAL,我不会得到双倍轮廓。

所以我的问题是:

  • 双重轮廓背后的原因是什么?为什么 CV_RETR_EXTERNAL 可以解决问题?
  • 获得点数最多的轮廓并不一定意味着它是最长的,对吧?由于 CV_CHAIN_APPROX_SIMPLE 标志。例如,CV_CHAIN_APPROX_NONE 会解决这个问题吗?

【问题讨论】:

    标签: opencv opencv-contour


    【解决方案1】:

    问:双重轮廓背后的原因是什么,为什么CV_RETR_EXTERNAL能解决问题?

    A:OpenCV findCountours 标准模式是CV_RETR_LIST,它输出一条线,就像你的情况一样,内轮廓和外轮廓。 CV_RETR_EXTERNAL,如文档中所述,将仅输出“极端外部轮廓”。请注意,外轮廓并不意味着最长的轮廓。我建议您遍历CV_RETR_LIST 模式给出的所有轮廓并进行计算。

    问:得到点最多的轮廓并不一定意味着它是最长的,对吧?由于 CV_CHAIN_APPROX_SIMPLE 标志。例如CV_CHAIN_APPROX_NONE会解决这个问题吗?

    答:第一个问题是正确的,如果您的 findCountours 方法与 CV_CHAIN_APPROX_NONE 不同。 CV_CHAIN_APPROX_NONE 也确实会解决这个问题,因为它会“绝对存储所有轮廓点”,但如果您更喜欢使用任何其他方法,您也可以将所有点之间的距离相加。

    【讨论】:

    • 您好 Berriel,谢谢您的回答。为了澄清一些事情,我还有一个问题。如果实际上我想做的是找到最长的外轮廓,那么我应该设置 CV_RETR_EXTERNAL 标志,然后我可以自己计算结果轮廓的长度,或者我可以使用 CV_CHAIN_APPROX_NONE 并比较点数以获得结果中的最长轮廓。我没听错吗?
    • 实际上,由于CV_RETR_EXTERNAL 仅返回“极端外轮廓”,如文档中所述,您必须确保在您的问题中,任何内轮廓都必须更短。最安全/更通用的方法是获取所有轮廓(例如,使用CV_RETR_LIST 作为模式)和所有轮廓点(使用CV_CHAIN_APPROX_NONE 作为方法),然后遍历返回的轮廓列表并计算它们的点(或计算点之间的总距离)。好吗?
    • 有没有办法改变我们得到的点的密度?
    • @AnkitKumar 默认不是,但你可以随时插入它们
    猜你喜欢
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 2019-01-03
    相关资源
    最近更新 更多