我需要从视频中检测道路车道。这是我的方式。
cv2.equalizeHist
cv2.adaptiveThreshold
skimage.morphology.skeletonize
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
函数所做的事情,我相信会有很多不必要的线条被绘制出来。
调整参数后,我得到了一个相当不错的结果,但这只是一张图片。我不认为这对于一个会不断变化的视频会有好处。 最让我烦恼的是关于我绘制所需线条的算法(即道路车道)。有没有更好的方法?至少比我好。
这是我的结果:
答案 0 :(得分:6)
我建议考虑使用概率Hough线变换来满足您的应用需求。在OpenCV的Python API中,它在函数cv2.HoughLinesP
中实现。这实际上会为您提供线段,因此您无需计算端点。它也比标准的Hough Line变换快得多。
但是有一些权衡取舍。例如,您可能需要添加逻辑以将线段拼接在一起。另一方面,我发现这并不是一件坏事。我的一个玩具项目(一个自动驾驶的微型公共汽车),采用这种方法,并有单独的线段拼接在一起,使得更容易处理弯曲的道路,标准的霍夫线变换将不会给你任何线路
希望有所帮助。
编辑:关于线段“拼接”的细节,这取决于你想要完成的事情。如果您只想显示道路,并且您对线段之间存在间隙感到满意,则可能不需要进行任何拼接 - 只显示所有线段。在我的应用中,我需要确定车道的曲率,所以我做了一些缝合来建立每个道路车道的模型,其中包括车道的平均坡度 - 用作负责控制车道的模块的输入。伺服相应地移动车轮。
通过“拼接”我并不意味着任何特别复杂的东西,但我不知道任何特定的OpenCV功能来实现它。我只需要一种相关线段的方式,它们是同一条线的一部分。因此,我从图像顶部向下处理从HoughLinesP
返回的线段,并使用每个线段的斜率和y轴截距来确定线段的相交位置。