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

时间:2016-04-13 12:47:57

标签: python algorithm opencv image-processing hough-transform

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

  1. 通过切片图像确定感兴趣区域(ROI)(聚焦中间部分)
  2. 灰度显示投资回报率
  3. 使用cv2.equalizeHist
  4. 将灰度级投资回报率均衡
  5. 将高斯模糊应用于(3)
  6. 使用cv2.adaptiveThreshold
  7. 的阈值(4)
  8. 使用skimage.morphology.skeletonize
  9. 进行Skeletonize(5)
  10. 在(6)
  11. 上应用cv2.HoughLines

    对于cv2.HoughLines,我设置为:

    1. 如果rho为正(这意味着直线向右倾斜(自下而上),它只会在特定角度绘制直线(我设置角度范围) )
    2. 如果rho为负数(直线向左倾斜(自下而上),则只会在某个角度绘制直线)
    3. 这是我绘制线条的代码:

      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 个答案:

答案 0 :(得分:6)

我建议考虑使用概率Hough线变换来满足您的应用需求。在OpenCV的Python API中,它在函数cv2.HoughLinesP中实现。这实际上会为您提供线段,因此您无需计算端点。它也比标准的Hough Line变换快得多。

但是有一些权衡取舍。例如,您可能需要添加逻辑以将线段拼接在一起。另一方面,我发现这并不是一件坏事。我的一个玩具项目(一个自动驾驶的微型公共汽车),采用这种方法,并有单独的线段拼接在一起,使得更容易处理弯曲的道路,标准的霍夫线变换将不会给你任何线路

希望有所帮助。

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

通过“拼接”我并不意味着任何特别复杂的东西,但我不知道任何特定的OpenCV功能来实现它。我只需要一种相关线段的方式,它们是同一条线的一部分。因此,我从图像顶部向下处理从HoughLinesP返回的线段,并使用每个线段的斜率和y轴截距来确定线段的相交位置。