继续研究自动驾驶的一些常用套路。这次是车道线的识别。本次学习途径是清研车联的《智能网联汽车电子控制系统工程师》课程下的《Matlab电子系统开发与建模》,如有错误,还请指出。
废话,不识别车道线,你的车要在道路上乱撞吗?咳咳,正经来说,当自动驾驶的车辆识别出车道线后,就能定位自己在道路中的位置,其它车辆在道路中的位置,就能规划接下来的行进路线,其作用自然不言而喻了。车辆一般使用前置摄像头(已完成标定)获取前方道路的图像,将图像传递给处理器,处理器对图像进行鸟瞰试图的转化、进行二值化、进一步识别出特征线(即车道线)、将车道线数据转到世界坐标系、对车道线进行二次曲线的拟合、将拟合得到的理论车道线追加到原始图像上等等。(这一个完整的流程竟然花了1周才走通。)
一般的摄像头拍出来的照片都是存在失真的,最明显的例子就是手机拍摄人像时,发现位于边缘处的人物“畸变”,都认不出来了。不过好在一个摄像头拍出来的图片都是按照同样的方式畸变的,所以只要标定一次这个相机的参数(内参、外参),就可以用来纠正这个相机拍摄的所有图片。
也不要以为这个标定很难,Matlab有自带的相机标定模块,只要给它一堆(需要标定的相机拍摄的)棋盘格图片,它就能把标定出参数来,封装在某个参数集 合里,剩下的就是利用这堆打包的参数了。上图中标定的图片,都是我在网上找到的一个棋盘格图片,然后拿手机,从各个方向拍了些照片,作为素材的。假设我们有一张如下的道路图片,来自车辆摄像头拍摄,然后经过了按照上述流程进行相机标定后对图片进行了纠正。
接下来,我们需要在Matlab中调用鸟瞰试图的参数进行转换;
bevc = load("birdsEyeConfig.mat");
birdsEyeViewImage = bevc.birdsEyeConfig.transformImage(I);
imshow(birdsEyeViewImage);
结果如下所示。虽然有一些噪点,但车道线还是很明显的。
上图中,我们终于将车道线标记出来了,也就是识别成功了,但是这个其实还是一张图片,是一张黑白图片,放在坐标中来看就是某些点为真,某些点非真。为此我们需要将这些真值点找出来,获得每个真值点的坐标。这样,我们就获得了图片的坐标。再将图片的坐标转到世界坐标系下去。 [r,c] = find(birdsEyeBW)
xyBoundaries = imageToVehicle(bevc.birdsEyeConfig,[c,r]);
获得了车辆坐标系(世界坐标系)下的标记点数据以后,我们需要利用这些数据进行曲线拟合,得到描述曲线的二次曲线方程的参数。
在本例中,我们会得到两条曲线的参数描述两条车道线。我们将数学模型叠加到原始的图像中,就有了以下的效果,车道线上被覆盖了两条拟合的曲线/直线。我们再回顾下整个过程,其是代码量相当少(如下图)。很多流程都被封装到了子函数内,只需要定义一下参数就行。理解流程需要10分钟,理解参数需要100分钟,敲代码需要1分钟。