【问题标题】:A good approach for detecting lines in an image?检测图像中线条的好方法?
【发布时间】:2013-05-15 23:14:52
【问题描述】:

我编写了一些代码,使用 OpenCV 库来检测画在草地上的白线。我需要有人对我使用的方法发表意见(因为我确信有比我更好的方法)。另外,我得到的结果并不像我预期的那么好,因为图像的细微变化需要调整参数(并且我需要对固定参数进行操作)。

到目前为止我的方法:

  1. 从网络摄像头抓取图像(并明显变成灰度)
  2. 通过阈值过滤器运行它(使用 THRESH_TO_ZERO 模式,它会将低于阈值的所有像素归零)。
  3. 模糊图像
  4. 通过侵蚀过滤器运行它
  5. 通过 Canny 边缘检测器运行它
  6. 最后,获取这个处理后的图像并使用概率霍夫变换 HoughLinesP 找到线条

我应该改变过滤器的顺序吗?

附:我不太关心处理能力;我在 GPU 上运行 HoughLinesP B-)

另外,这是一张示例图片:

我得到的结果: 精明的 没有精明(稍微调整参数)

任何帮助或指导将不胜感激!我只是不知道如何改进它!

更新 根据选择的答案使用非常快速的骨架实现(带有大量模糊)后,我得到了这个:

【问题讨论】:

  • 在阈值处理后运行模糊是有原因的?在我看来,颠倒这两个步骤更合乎逻辑
  • 你好,快速搜索给了我以下vision.caltech.edu/malaa/publications/aly08realtime.pdf对应的opencv和matlab代码也可以...code.google.com/p/caltech-lane-detection
  • @NicolaPezotti 我不知道我为什么这样做。本来没用blur的,后来加了。我会尝试颠倒顺序并回复您。无论如何,谢谢!
  • @G453 这看起来很有希望!感谢您的链接!我会阅读它,看看我能做什么......
  • @Cashew 通常是在应用阈值之前应用低通滤波器以消除高频噪声的好习惯(在这种情况下,我们可以将草纹理视为噪声)。

标签: opencv image-processing feature-detection edge-detection hough-transform


【解决方案1】:

根据您的最后一个结果(在骨架过滤器之后),您会得到许多小片段。我认为您在执行本文中所做的工作时处于非常有利的位置:

http://www.cs.ubc.ca/~lowe/papers/aij87.pdf

基本上,它们提供了根据图像中不同特征属于同一对象的可能性来重新组合图像中不同特征的工具。所以你所要做的就是将你的结果输入到他们的算法中,你可能会得到一条结果。

【讨论】:

    【解决方案2】:

    RANSAC算法可能是个好方法。此方法类似于regressioninterpolation 方法。您应该在使用edge detection 后提取分数(我认为最好的方法是canny)。然后你应该找到最好的线路。为了找到通过多个点的线,有不同的方法,例如线性回归或 RANSAC。您可以在this link 中找到有关RANSAC 算法的实现和注释。

    请注意,RANSAC 和另一个有用的算法是 already implemented in OpenCV(据我所知在 3.2 版中)和 Accord NET(用于图像处理的免费库)。

    【讨论】:

      【解决方案3】:

      我将 Canny 用于室内图像,但对于室外,我发现 Laplace 滤波器和 Sobel 滤波器比应用概率霍夫线变换 (PHT) 更合适。

      如果你想加粗你的线条,你应该在 Laplace 之后尝试Sobel operator,最后是 PHT。如果你的形象太爱管闲事,它可能会变得更糟。

      【讨论】:

      • 对不起,PHT 是什么?请详细说明并更具体。 :)
      • 抱歉,PHT 代表概率霍夫线变换。
      • 哦,好的。但是,如果你的边缘有点粗糙和弯曲(就像我上一张照片一样),你如何让你的 PHT 抓住线条?
      • 应该在什么阶段应用溶解?你的意思是在 PHT 之前?
      • 是的,在 PHT 之前,我还增强/锐化了图像的部分。
      【解决方案4】:

      我会尝试使用图像的skeleton representation。在这里,您的精明的问题在于,由于线的宽度,它基本上会导致两条线。

      然后我将对其应用霍夫变换。

      【讨论】:

      • 太棒了!我正在使用侵蚀来达到相同的结果,但我从没想过动态应用它(足以让只剩下一行)......我会试一试,并会回复你。谢谢!
      • 天哪,这正是我所需要的!太棒了!事实证明,当我需要一些额外的步骤来获得骨架时,我只是应用了侵蚀过滤器!现在,我得到了完美的线段。我需要做的就是弄清楚如何将它们加入一条线......非常感谢! :D
      • 这可能是一个愚蠢的问题,但必须在骨架表示之后应用精明过滤器,不是吗?所以它不能替代精明的边缘检测器?
      • @BlackMamba 很抱歉回复晚了。骨架表示为您留下单像素宽度的“骨架”。所以在那之后没有必要运行一个精明的边缘检测器,因为你只剩下边缘了。
      • @JonesV,链接已损坏。
      【解决方案5】:

      一种可能的解决方案是获取您从精明边缘检测中获得的所有边缘点,并在这些点上使用线性最小二乘法(可能是迭代)拟合一条线。这样,您总能得到一条“最适合”边缘点的线。这种方法几乎不涉及参数化。

      【讨论】:

      • 嗯,所有的预处理(包括Canny)都有很多参数。但是有一个问题:如果我使用最小二乘法与霍夫线变换有什么区别?是否有显着优势(除了计算能力,这对我来说并不重要)
      • 最小二乘法的优点是将单行作为输出,而霍夫变换可能会提供多行(我在您的结果中注意到了这一点)。关于敏感性,我同意,这就是为什么您可能可以使用迭代方法来做,其中每次迭代都会过滤掉异常值。或者,您可以执行与最小二乘相结合的 RANSAC,甚至可以单独执行 RANSAC 以获得您需要的结果。
      • RANSAC 听起来是个好主意,但我现在时间不多了,我可能会采用另一种方法。不过谢谢!
      猜你喜欢
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 2014-06-16
      • 2010-10-15
      • 1970-01-01
      相关资源
      最近更新 更多