Python 和 OpenCV - 改进我的车道检测算法

Posted

技术标签:

【中文标题】Python 和 OpenCV - 改进我的车道检测算法【英文标题】:Python and OpenCV - Improving my lane detection algorithm 【发布时间】:2016-08-04 13:53:03 【问题描述】:

我需要从视频中检测道路车道。这是我的做法。

    通过对图像进行切片来确定感兴趣区域 (ROI)(聚焦中间部分) 对 ROI 进行灰度化 用cv2.equalizeHist均衡灰度ROI 对 (3) 应用高斯模糊 阈值 (4) 使用 cv2.adaptiveThreshold 使用skimage.morphology.skeletonize 骨架化 (5) 在 (6) 上应用 cv2.HoughLines

对于cv2.HoughLines,我这样设置:

    如果rho为正(表示直线向右倾斜(自下而上),只有在一定角度时才会画线(我设置了角度的范围)) 如果rho 为负数(直线向左倾斜(自下而上),只有在特定角度时才会画线)

这是我绘制线条的代码:

lines = cv2.HoughLines(image_bin, 1, np.pi/180, 50)
    try:
        range = lines.shape[0]
    except AttributeError:
        range = 0

    for i in xrange(range):
        for rho, theta in lines[i]:
            if rho > 0 and (np.pi*1/10 < theta < np.pi*4/10):
                a = np.cos(theta)
                b = np.sin(theta)
                x0 = a * rho
                y0 = b * rho
                x1 = int(x0 + 1000 * (-b))
                y1 = int(y0 + 1000 * (a))
                x2 = int(x0 - 1000 * (-b))
                y2 = int(y0 - 1000 * (a))

                cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))

            if rho < 0 and (np.pi*7/10 < theta < np.pi*9/10):
                a = np.cos(theta)
                b = np.sin(theta)
                x0 = a * rho
                y0 = b * rho
                x1 = int(x0 + 1000 * (-b))
                y1 = int(y0 + 1000 * (a))
                x2 = int(x0 - 1000 * (-b))
                y2 = int(y0 - 1000 * (a))

                cv2.line(roi, (x1, y1), (x2, y2), (0, 255, 0))

如果我不做我刚才对cv2.HoughLines函数所做的事情,我相信会画出很多不需要的线条。

在调整参数等之后,我得到了一个相当不错的结果,但那只是一张图片。我认为这对于不断变化的视频来说不会那么好。 最困扰我的是我绘制所需线条(即道路车道)的算法。有没有更好的办法?至少比我的好。

这是我的结果:

原图:

ROI 的均衡直方图、阈值化和骨架化图像:

最终结果:

【问题讨论】:

【参考方案1】:

我建议您考虑为您的应用程序使用概率霍夫线变换。在 OpenCV 的 Python API 中,它在函数cv2.HoughLinesP 中实现。这实际上会给你线段,所以你不需要计算端点。它也比标准霍夫线变换快得多。

虽然有一些取舍。例如,您可能需要添加逻辑来将线段缝合在一起。另一方面,我发现这并不是一件坏事。我的一个玩具项目(一辆自动驾驶微型巴士)使用了这种方法,并且将单独的线段拼接在一起使得处理弯曲的道路变得更容易,其中标准霍夫线变换根本不会给你任何线条.

希望对您有所帮助。

编辑:关于线段“拼接”的细节,这取决于您要完成的任务。如果您只想显示道路,并且对线段之间存在一些间隙感到满意,则可能不需要进行任何拼接 - 只需显示所有线段即可。在我的应用程序中,我需要确定车道的曲率,所以我做了一些拼接来建立每条道路车道的模型,其中包括车道的平均坡度 - 用作负责控制的模块的输入伺服以相应地移动车轮。

我所说的“缝合”并不是指任何特别复杂的东西,但我不知道有任何特定的 OpenCV 函数可以完成它。我只需要一种关联线段的方式,它们是同一车道的一部分。因此,我从图像顶部向下处理从HoughLinesP 返回的线段,并使用每个线段的斜率和 y 截距来确定线段相交的位置。

【讨论】:

如何“缝合”线条?抱歉,还是编程和图像处理的初学者。 我添加了一些注释。很抱歉没有提供任何代码。它是用 C++ 编写的,具体实现与您的非常不同 - 基本上,我只是没有足够的时间来适应您的应用程序。

以上是关于Python 和 OpenCV - 改进我的车道检测算法的主要内容,如果未能解决你的问题,请参考以下文章

基于Python+OpenCV车道线检测(直道和弯道)

python+openCV (入门级)车道线检测 学习笔记

使用 OpenCV (Python) 改进轮廓检测

OpenCV 4.0 车道检测

OpenCV在车道线查找中的使用

OpenCV实战案例——车道线识别