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

标签 python algorithm opencv image-processing hough-transform

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

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

对于 cv2.HoughLines,我设置为:

  1. 如果rho是正数(这意味着直线向右倾斜(自下而上),只有在一定角度时才会画线(我设置了范围角度))
  2. 如果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 函数执行上述操作,我相信会绘制出很多不需要的线条。

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

这是我的结果:

原图: The original image

ROI 的均衡直方图、阈值化和骨架化图像: Equalized Histogram, thresholded, and skeletonized

最终结果: Final result

最佳答案

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

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

希望对您有所帮助。

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

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

关于Python 和 OpenCV - 改进我的车道检测算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36598897/

相关文章:

c++ - OpenCV简单2D矩阵乘法失败

algorithm - 控制流图遍历 - BFS,但确保前辈被访问

c++ - 在 Ubuntu 上链接 OpenCV 2.3.1

python - 删除列表中字符串中的日期和年份重复项

python - Django settings.py 未更新

java - 将整数数组划分为 2 个不相连的部分

algorithm - '3 jugs of water' 的状态图

python - opencv cap.read 有一个属性错误。如何排除故障?

python - 使用Python删除不包含正则表达式匹配的单元格/行

python - Pyspark 列在查找前几行和计算时生成