0

我正在尝试根据视频源的形状特征(例如:面积、轮廓长度等)在视频源中执行暗(几乎是黑色)对象检测,但我在检测二进制掩码中的轮廓时遇到问题。

有时即使对象没有改变形状并且轮廓是从仅包含一个紧凑 blob 的简单蒙版派生的,轮廓也没有关闭(我可以看出,因为我使用 CV_FILLED 选项显示它,并且对于许多帧轮廓已填充),并且由于该计算区域实际上不可信(值降低到几个像素)。

我还注意到,当对象的轮廓未闭合时,长度大约是预期的 2 倍(这是有道理的)。

为什么简单斑点的轮廓有时会打开有时会关闭,我如何强制它们始终关闭?我已经尝试过凸包,并将轮廓的第一个点复制到它的末端,但它没有用。

我的方法的步骤如下:

  1. 将图像转换为灰度
  2. 执行阈值化、腐蚀和膨胀以消除噪声并改善“形状”
  3. 使用 Canny 边缘检测器只得到边缘
  4. 使用 findContours 获取等高线及其区域:
  5. 使用 arcLength 计算等高线和其他特征的长度。
4

1 回答 1

0
  1. 使用 Canny 边缘检测器只得到边缘

这是一个经典的错误。在步骤 2 之后和期间,我假设您有一个二进制图像,即带有一堆填充的白色斑点的黑色图像,这些斑点表示您要查找的区域。这正是cv::findContours起作用的。

当你进行边缘检测时,你实际上将那些漂亮的填充区域转换成一堆非常细长的、可能但不一定是封闭的线,这些线包围着你以前的区域,这会把一切都搞砸了。因此cv::findContours将完全返回,一堆非常细的轮廓。这些轮廓实际上也是封闭的,因为它们代表一个封闭的多边形,最后一个点连接回第一个点,只是这个多边形环绕着边缘检测产生的那些细线,这就解释了为什么它们的面积非常小并且周长大约是您期望的两倍。它基本上将边缘检测产生的那些线条视为实际轮廓,而不是非常薄区域您想找到的边界轮廓,这可能不是您想要的。

如果这些边界线是闭合的并且您只检索外部轮廓(例如,使用CV_RETR_EXTERNAL),您可能会得到您期望的大致相同的适当区域轮廓,但这不能保证并且很容易搞砸。

因此,简单的解决方案是放弃 Canny 边缘检测步骤,直接处理正确的二值图像,正如cv::findContours通常所期望的那样。

于 2017-08-02T14:04:32.973 回答