OpenCV findContour 方法返回 "doubled" 轮廓

OpenCV findContour method gives back "doubled" contour

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

示例图像如下所示:

我使用的是 OpenCV 教程页面中的 same sample code。有一点不同,我将阈值设置为固定数字,即 100。

主线是这条:

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

调用上述函数后,我遍历找到的 contours 并检查哪一个最长,然后我保存最长的一个。最长下我是说哪个积分最多

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

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

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

所以我的问题是:

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

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

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

答:如果您的 findCountours 方法与 CV_CHAIN_APPROX_NONE 不同,第一个问题是正确的。 CV_CHAIN_APPROX_NONE 确实会像 "store absolutely all the contour points" 一样解决这个问题,但如果您更喜欢使用任何其他方法,也可以对点之间的所有距离求和。