0

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

示例图像如下所示:

轮廓查找的示例图像

我正在使用与OpenCV 教程页面完全相同的示例代码。有了一个差异,我将阈值设置为一个固定数字,即 100。

主线是这一行:

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

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

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

在此处输入图像描述

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

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

所以我的问题是:

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

1 回答 1

3

问:双重轮廓背后的原因是什么?为什么 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可以解决此问题,因为它将“绝对存储所有轮廓点”,但如果您更喜欢使用任何其他方法,您也可以对点之间的所有距离求和。

于 2015-08-20T23:41:32.373 回答