智能进化
首发于智能进化
高级车道线识别算法

高级车道线识别算法

简单车道线识别一文中介绍了5钟算法,但它们都不能很好地解决第三种复杂场景中的阴影、路面杂色、光线强弱等干扰问题,另外还有一个特别的问题就是如何正确地识别弯道。今天继续介绍一些高级算法来识别车道线。这些算法是:

1. 相机图像校准算法。主要用于纠正经过相机镜头成像后图片四边的变形或者拍摄物体与相机角度不平行、不正对;

2. 车道线透视图角度的拉平,转换成鸟瞰图下的平行线;

3. 用多种Sobel梯度过滤算法,如x轴方向、正切方向、向量值大小来滤除噪声;

4. 直方图峰值法寻找窄窗内的白线

5. 二阶曲线拟合确定相关系数,计算曲率和弯道半径


图像边缘容易变形是由相机镜头的透镜形成的。为了保证成像的准确性,每张待处理的图像先要用cv2.undistort(image, mtx, dist, None, mtx)进行矫正。得到如下图的第二张。

相机成像根据物体远近形成透视图效果,即我们看到的车道线在远处渐渐汇聚成一点。但现实世界它们是平行的,就像从空中视角向下看。所以通过代码

M = cv2.getPerspectiveTransform(src, dst)
unwarped = cv2.warpPerspective(img, M, img_size, flags=cv2.INTER_LINEAR)

将车道线转换成平行图像,得到下图。

以上就是先期的处理,目的是为了后面能够正确地解析二次曲线的相关系数和计算曲率半径,最终识别弯道车道线。

在简单车道线识别中我们用到了Canny轮廓过滤。其缺点是它把图像中所有带边缘的物体都呈现了出来,而我们只关心车道线。所以本文介绍另外一种轮廓过滤算法叫Sobel Operator,其实Canny的算法基础就是来自于Sobel。用两张最难辨识的图像做测试。

用Sobel算法,如果从x轴方向去过滤,很多水平方向的轮廓就被滤掉了,我们得到图像:

如果从Sobel x 和Sobel y的向量大小上去过滤,更多短向量被过滤掉了,得到图像:

如果从一个给定的正切方向去过滤,除了车道线,整个图像都被噪声化了,得到图像:

将这些不同的算子进行结合,我们关心的车道线已经可以以二进制的形式清楚地呈现出来,得到图像:

但左边那张在白色水泥地的那段黄线不见了。这是因为我用的Sobel阈值上限都比较低,用来抑制白色水泥带来的噪声。而黄线,由于它跟白色水泥地的对比度太接近,被一起过滤掉了。必须通过其他方法把它找回来。我采用颜色选择过滤法。但熟知的RGB颜色空间要过滤出黄线来阈值太高,在(200,255)之间,对于测试1的这张图片中高对比度的白色水泥会跟黄线一起保留下来,根本无法去除。


所以考虑HLS颜色空间。S通道在阈值(110, 130)之间就能同时保留黄线滤除白色水泥。

这样将颜色S通道和Sobel混合,得到图像:

过滤的处理到此结束。下面是寻找车道线了。算法采用直方图峰值法。即取包含有车道线的下半部分图像做x轴方向的直方图,得到下图。可以看见左侧有明显峰值,右侧不甚明显。利用车道线位置在视角中基本不变的特点,在左右设定两个搜索窗,右侧的车道线位置就可以找到了,在窗内对应一个小高峰。

求解曲线拟合相关系数用np.polyfit(y, x, 2)。这里y在前主要是因为车道线在图像中是垂直方向的且取值范围固定,曲线在x轴方向应变。

通过曲线拟合相关系数画出车道线:

ploty = np.linspace(0, combined.shape[0]-1,combined.shape[0] )
curvleft = left_fit[0]*ploty**2 +left_fit[1]*ploty + left_fit[2]
curvlright = right_fit[0]*ploty**2 +right_fit[1]*ploty + right_fit[2]
plt.plot(curvleft,ploty)
plt.plot(curvright,ploty)


计算曲率半径:


最后成图:

然后是我完成的车道线标识视频,基本很稳定。

https://www.zhihu.com/video/888811814475935744

发布于 2017-09-06

文章被以下专栏收录