在图像中检测线条的好方法是什么?

33
我已经编写了一些使用OpenCV库的代码,用于检测草地上涂白色的线条。我需要有人对我使用的方法提供意见(因为我确信肯定有比我的更好的方法)。此外,我得到的结果不如预期,因为图像中的轻微变化需要调整参数(而且我需要操作固定的参数)。
到目前为止,我的方法是:
  1. 从网络摄像头获取图像(显然转换为灰度)
  2. 将其通过阈值过滤器运行(使用THRESH_TO_ZERO模式,在这种模式下,它会将低于阈值的任何像素值都归零)。
  3. 模糊图像
  4. 运行它通过腐蚀过滤器
  5. 运行它通过Canny边缘检测器
  6. 最后,使用Probabilistic Hough Transform HoughLinesP找到这个处理过的图像并找到线条。
我应该改变过滤器的顺序吗?
附带一张样本图片: 原始图像 我得到的结果: 带有canny 带canny 没有canny(稍微调整了参数) 这次没有canny 任何帮助或指导都将不胜感激!我只是不知道该怎么做才能改进它!
更新: 使用所选答案的快速骨架实现(大量模糊)之后,我得到了这个结果: 奏效了!

1
你为什么在阈值处理之后再进行模糊处理?我认为倒过来会更合理。 - Nicola Pezzotti
1
嗨,快速搜索给了我以下结果:http://www.vision.caltech.edu/malaa/publications/aly08realtime.pdf 相应的OpenCV和Matlab代码也可用...https://code.google.com/p/caltech-lane-detection/ - G453
@NicolaPezzotti 我不知道为什么我那样做。起初我没有使用模糊,然后我添加了它。我将尝试倒转顺序并回复您。无论如何感谢您! - Cashew
@G453 这看起来非常有前途!感谢提供链接!我会阅读一下,看看我能做些什么... - Cashew
@NicolaPezzotti 在我尝试了骨架方法之后,我意识到在阈值之前执行模糊处理可以使结果更好!谢谢你!:D - Cashew
1
通常情况下,在应用阈值之前,应该使用低通滤波器来消除高频噪声(在这种情况下,我们可以将草地纹理视为噪声),@Cashew。 - Nicola Pezzotti
5个回答

22
我会尝试使用图像的骨架表示。这里你的Canny算法存在问题,因为由于线条宽度的缘故,它基本上会导致两条线。
然后我会对其应用霍夫变换。

太好了!我一直在尝试使用腐蚀操作来达到相同的效果,但我从未想过动态应用它(只需保留一条线)...我会尝试一下,并会回复你。谢谢! - Cashew
2
哇塞,这正是我需要的!太棒了!原来我只是应用了腐蚀滤镜,而我需要额外的步骤来获取骨架!现在,我得到了完美的线段。我只需要想办法将它们连接成一条线...非常感谢你! :D - Cashew
这可能是一个愚蠢的问题,但是在骨架表示之后必须应用canny滤波器,不是吗?因此它不能替代canny边缘检测器? - BlackMamba
@BlackMamba 很抱歉回复晚了。骨架表示法让你得到单像素宽度的“骨架”。因此,在那一点之后没有必要运行Canny边缘检测器,因为你所剩下的只是边缘。 - Cashew
@JonesV,链接已损坏。 - CroCo
@JonesV,你能帮我看看这个问题吗:https://dev59.com/WJvga4cB1Zd3GeqP3IXX - Haresh Chhelana

5

一种可能的解决方案是,使用Canny边缘检测得到的所有边缘点,并使用线性最小二乘法(可能是迭代的)拟合这些点。这样,您总是可以得到一个“最佳拟合”边缘点的单条直线。这种方法几乎没有参数化。


所有的预处理(包括Canny)都有很多参数。不过,有一个问题:如果我使用最小二乘法而不是霍夫线变换,会有什么区别?除了计算能力(对我来说并不重要)之外,是否有显著的优势? - Cashew
1
最小二乘法的优势在于可以得到一条单一的直线作为输出,而霍夫变换可能会提供多条直线(这是我在你的结果中注意到的)。关于灵敏度,我同意,这就是为什么你可能需要一个迭代方法,在每次迭代中过滤掉异常值。或者,您可以执行RANSAC与最小二乘法相结合,甚至只使用RANSAC来获得所需的结果。 - Zaphod
RANSAC听起来不错,但我现在时间不够了,我可能会选择另一种方法。谢谢! - Cashew

5

我在处理室内图像时使用Canny算法,但对于室外图像,我发现Laplace和Sobel滤波器更适合,并应用概率霍夫线变换(PHT)。

如果您想要加粗线条,可以尝试在Laplace之后使用Sobel算子,最后再进行PHT。如果图像过于嘈杂,效果可能会变差。


抱歉,请问PHT是什么?请详细解释并更加具体。 :) - Cashew
抱歉,PHT代表概率霍夫线变换。 - Elod
哦,好的。但是如果你的边缘有些粗糙和弯曲(就像我上一张图片中的那样),你怎么让你的PHT抓住这些线呢? - Cashew
在哪个阶段应该应用溶解?你是指在PHT之前吗? - Cashew
在 PHT 之前,我还用图像的部分进行了增强和锐化。 - Elod

1

RANSAC算法可能是一个很好的方法。这种方法类似于回归或插值方法。您应该在使用边缘检测后提取点(我认为最好的方法是canny)。然后,您应该找到最佳线路。要查找通过几个点的线路,有不同的方法,例如线性回归或RANSAC。您可以在this link中找到关于RANSAC算法的实现和注释。

请注意,RANSAC和另一些对此目标有用的算法已经在OpenCV(据我所知,在版本3.2中)和Accord NET(一个免费的图像处理库)中实现了。


0

在经过骨架滤波器后,您会得到许多小片段。我认为此时您已经处于非常好的位置,可以实现本文中所做的工作:

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

基本上,它们提供了工具来根据不同特征在图像中的相似度将其重新组合为同一个对象。所以你只需要将你的结果输入到他们的算法中,很可能会得到一条单独的线作为结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接