我需要从视频中检测道路车道。这是我的做法。
- 通过对图像进行切片(聚焦中间部分)来确定感兴趣区域 (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
函数执行上述操作,我相信会绘制出很多不需要的线条。
在调整参数等之后,我得到了一个很好的结果,但这只是一张图片。我认为对于不断变化的视频来说不会那么好。 最让我困扰的是我绘制所需线条(即车道)的算法。有没有更好的办法?至少比我的好。
这是我的结果:
最佳答案
我建议考虑为您的应用程序使用概率霍夫线变换。在 OpenCV 的 Python API 中,它在函数 cv2.HoughLinesP
中实现。这实际上会给你线段,所以你不需要计算端点。它也比标准霍夫线变换快得多。
虽然有一些权衡。例如,您可能需要添加逻辑以将线段缝合在一起。另一方面,我发现这并不是一件坏事。我的一个玩具项目(自动驾驶微型巴士)使用了这种方法,并且将单独的线段缝合在一起使得处理弯曲的道路变得更加容易,在这些道路上,标准霍夫线变换根本不会给你任何线.
希望对您有所帮助。
编辑:关于线段“拼接”的细节,这取决于您要完成的任务。如果您只想显示道路,并且您对线段之间存在一些间隙感到满意,您可能不需要进行任何拼接 - 只需显示所有线段即可。在我的应用程序中,我需要确定车道的曲率,所以我做了一些拼接来建立每条车道的模型,其中包括车道的平均坡度——用作负责控制车道的模块的输入伺服相应地移动轮子。
我所说的“缝合”并不是什么特别复杂的意思,但我不知道有任何特定的 OpenCV 函数可以完成它。我只需要一种关联线段的方式,这些线段是同一车道的一部分。因此,我从图像顶部向下处理从 HoughLinesP
返回的线段,并使用每个线段的斜率和 y 轴截距来确定线段相交的位置。
关于Python 和 OpenCV - 改进我的车道检测算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36598897/