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

12
我需要从视频中检测道路车道。以下是我的实现方式。
  1. 通过切图(将焦点放在中间部分)确定感兴趣区域(ROI)
  2. 对ROI进行灰度处理
  3. 使用cv2.equalizeHist均衡化灰度ROI
  4. 对(3)应用高斯模糊
  5. 使用cv2.adaptiveThreshold阈值化(4)
  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
1个回答

6
我建议考虑在应用中使用概率霍夫线变换。在OpenCV的Python API中,它是在cv2.HoughLinesP函数中实现的。这将给你线段,因此你不需要计算端点。它比标准的霍夫线变换要快得多。
当然,有一些权衡。例如,您可能需要添加逻辑来拼接线段。另一方面,我发现这并不是什么坏事。我的一个玩具项目(自驾迷你巴士)使用了这种方法,在曲线道路上拥有单独的线段使得处理更容易,而标准的霍夫线变换不能给出任何线段。
希望这有所帮助。
编辑:关于线段“拼接”的细节,这取决于您想要实现什么。如果您只想显示道路,并且您对线段之间存在一些间隙感到满意,您可能不需要进行任何拼接-只需显示所有线段。在我的应用程序中,我需要确定车道的曲率,因此我进行了一些拼接,以建立每条道路车道的模型,其中包括车道的平均斜率-这被用作控制舵机移动轮子的模块的输入。
通过“拼接”,我并不特别指任何复杂的操作,但我不知道任何特别的OpenCV函数来完成它。我只需要一种将线段关联在同一车道中的方法。因此,我从图像顶部向下处理从HoughLinesP返回的线段,并使用每个线段的斜率和y截距确定线段将相交的位置。

我应该如何“拼接”这些行呢?抱歉,我对编程和图像处理都还是初学者。 - Hafiz Hilman Mohammad Sofian
我添加了一些注释。很抱歉没有提供任何代码。它是用C++编写的,而且特定的实现与你的非常不同 - 基本上,我只是没有足够的时间来适应你的应用程序。 - Aenimated1

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