今天给大家分享下自己多年来从事自动驾驶感知板块的一些经验、心得体会,希望能给想要从事感知和已经在做感知的朋友一些参考吧,一起学习,说的有不对的可以留言一起讨论。
1 刚开始
说实话我之前的工作压根都和自动驾驶占不到一点边,大学毕业为祖国奉献了两年,后来自费参加培训学习c/c++(我是自动化专业的,所以还是有些基础的。),然后找了一份相关的工作,后来发现就是写html、js以及cgi的,头两年感觉成长的还是很快,但是后面就觉得没有成长空间了,自己也挺内耗的,然后就开始寻找出路,直到2017年AlphaGo横空出世,我突然就想这是个机会,人工智能来了,我直接裸辞去学习深度学习。 在学习深度学习知识的时候,就接触到了神经网络相关知识:基础知识:Python、CNN、Pooling、RNN、LSTEM、感受野、IOU、loss function等;开源的模型:Yolo系列、MTCNN、DeepLabV3、Resnet等;开发框架:Pytorch、Tensorflow、Caffe等;数据集:VOC、Imagenet、kitti、cityscape等; 学下来还是觉得很感兴趣,前途一片光明啊,后面找工作就找到一家做自动驾驶的公司,做感知里面的模型开发。
2 入坑
2.1 模型篇
那是2018年下半年,开始做感知模型开发时就发现了各种问题。一是场景问题,受限于应用场景,现成的公开数据集都不是很合适或者说能用的不多,都需要基于自己的场景去采集数据,这是一个比较大的工程啊,我们当时自己搭建了一个简易采集设备,带整个团队去我们需要的场景去采集数据,这段时间还是比较辛苦。二是模型问题,受一些环境的限制,我们只有一个caffe的模型网络结构文件,没有办法在pytorch上进行训练,我们就开始将caffe的模型翻译到pytorch上,网络结构翻译起来还是比较顺利,但是loss function这步就比较困难了,由于模型是采用多头输出的方式,loss function的设计比较麻烦,后面经过多次测试还是弄出来了,这个也是比较磨练人的耐心的。三是标注问题,由于没钱请不起标注团队,我们就自己标,开始我们标注了大几千张,然后就拿这些数据训练模型帮我们自动标注数据,这样迭代可以提升不少效率,但是大部分还是需要人工再确认调整下,那段时间我们团队人眼睛都要看瞎了,重复性的机械工作大大降低了士气,大家都比较疲惫,不过好歹还是有些成果的。四是部署问题,模型训练好后到部署时,发现在嵌入式板子上推理时延比较大,想了一些解决办法:减小输入尺寸、模型剪枝等,最后通过一些工程处理基本满足要求。 这些是碰到的主要问题,我相信每一个搞深度学习模型的都碰到过这些问题。总结下搞深度学习项目的大概思路:1.要有数据闭环的思想 搞任何需要落地的深度学习项目都需要有数据闭环的概念。下图就是一个以数据为驱动的闭环系统,只有形成数据的闭环才能实现模型的快速迭代提升。
2.要有迭代的思想 这里的迭代的意思是:先快速搭建起MVP并跑通整个流程,然后基于数据驱动不断的发现、修正过程中的问题,而不是一开始就要做的很完美,在过程中去优化,职场中效率是第一位的。3.要有工程的思想 模型毕竟是基于数据驱动的,现实世界数据是无限的,不可能所有的数据都能采集到,这样模型必然会有失效的时候,这个时候就需要对结果做一些工程上的处理,比如加各种常识性的规则,避免模型失效导致安全问题,这个是致命的。4.要有多动手的思想 搞模型不要只会调参,你要充满好奇心,比如网络每一层卷积出来到底是个啥,长啥样,能不能可视化出来看下,还有数据增强,到底怎么增强的,增强后的图片又长啥样等等,如果你没有去看过,去想过,你怎么能解决模型训练过程中的各种问题,比如指标一直升不上去,你应该从哪些地方去思考、去排查等。要做到知行合一,想到就立马去做。
2.2 机器视觉篇
模型只是感知模块的一小部分功能,给模型提供输入的图像、相机属于机器视觉部分的知识。为了扩展自己的知识面又去学习了机器视觉相关的知识。1.传感器从相机选型、标定到应用相机选型详细的经验分享2.Opencv学习 a.cv::Mat的相关操作; b.学习图像各种应用,如特征提取、形态学运算、Canny边缘检测、Aruco识别; c.研究了图像的存储编排格式,如RGB、BGR、YUV等;3.相机坐标系 a.右手坐标系,大拇指为Z轴指向相机的前方,四指为X轴指向相机的右侧,四指弯曲向下为Y轴。
b.坐标系变换,世界坐标系怎么转换到图像坐标系。4.立体视觉 a.立体视觉成像原理; b.视差图计算; c.深度图转点云; d.立体匹配,极线矫正; 这里就不多说的,这个内容很多,感兴趣可以去了解下。下图是双目立体成像的基本原理。
这些大家可以先有一定的基础知识的了解,然后再在实际的工作中去边学习边使用,只有在真实的场景需求中才能更好的理解学习。5.透视变换 这个也是需要去学习了解的知识点,里面有个放射变换和单应性变换是比较重要的,像车牌识别、鸟瞰图等应用都会用到相关知识。
6.应用a.单目测距 通过单张图怎么估计障碍的距离,比较常用的就是地平面假设,还有就是迭代重投影,最后就是基于模型的方法。b.障碍物检测
- 在理想场景下也可以基于UV视差图来做,但是效果肯定没有那么好,如下图就是UV视差图。

- 利用双目得到的点云,通过点云聚类也可以检测出障碍物,但是双目点云识别距离只有10m左右比较近,而且越远误差越大。
c.语义分割
- 基本都是用模型的方法,如ppseg、yolo-seg、deeplab系列等;
- 如果只做地面的分割,还可以用上面提到的UV视差图中的V视差图做,通过拟合那条折线,在折线附近的点就是地面点。
d.BEV环视 通过4颗环绕车身的摄像头,利用透视变换和图像的拼接技术得到BEV鸟瞰图。 还有很多其他的应用,这里就不再详细说了。
2.3 点云篇
除了特斯拉的FSD走的纯视觉方案外,国内搞自动驾驶的主力传感器都是激光雷达,国内已经把激光雷达的成本打到很低了,所以基本上都会上激光雷达,所以点云的处理也是需要学习了解的知识。1.传感器知识激光雷达选型、标定及应用2.PCL知识 这个是搞点云必须要学习的三方库,里面的内容很全面,如点云滤波、点云聚类、点云平面拟合Ransac、点云分割等,需要认真学习,可以去跑下它提供的示例代码,看下效果,有一个具象的了解。下图就是点云的分割。
除了上面的一些基本算法,还需要了解每个点的数据结构,如pcl::PointXYZRGB、pcl::PointXYZI、pcl::PointXYZINormal等。3.应用a.障碍物检测和分割 主要分传统的方法和模型的方法。
- 传统的方法:主要就是使用pcl库里面的各种算法进行检测,还有就是自己写检测算法(能针对性优化计算量),pcl进行过程优化很困难,优点:速度快,对算力要求低,缺点:没有语义信息(只能结合相机提供)
- 模型的方法:主要基于三维卷积模型或者将3维降为2维再进行卷积,如pointpillars、pointnet等,优点:有语义信息、障碍物稳定、鲁棒性好,缺点:耗算力、速度慢、标注成本高、训练困难。
b.三维建图 借助slam技术构建场景的三维点云地图,用于数字孪生、三维建模等。c.点云匹配 通过pcl提供的ICP、NDT等匹配算法,计算2帧点云之间的位姿关系,可用于点云定位、点云拼接等。
2.4 Slam篇
Slam同步建图和定位,看起来和感知模块没有任何关系,但是作为整个自动驾驶系统来说是slam是很重要的技术,在一些遮挡场景或者地下车库场景,卫星信号很弱,导致定位丢失,这个时候slam就发挥巨大的作用,提供实时车辆定位,这样整个系统才不会失效。而且slam需要的传感器数据和感知模块一样的,还有slam前端的一些算法需要以来感知的处理结果,如动态障碍物的剔除、地面过滤、点云语义信息等,所以和感知还是有强关联的。slam是一个综合性很强的系统,学习起来可能会比较困难,但可以先学习基础知识。1.slam十四讲 我也是看高翔的《slam十四讲》慢慢学习基础知识的,先学一遍,后面再在实际的项目中去磨练吧。2.三方库 需要学习一些三方库的使用,像eigen、g2o、ceres、gtsam等。3.ROS学习 搞机器人基本都需要学习ROS的知识,目前基本开源的slam框架都需要用ROS的。4.看开源框架 可以从github上去下载一些开源的框架,如ORB-Slam、Fast-Lio2、R3live、Fast-LVIO等,多去分析学习看下他们的算法框架和代码框架,跑下demo示例,在使用中去学习。
2.5 其他篇
在实际开发中也是需要去学习了解的一些知识吧。1.Docker 这个是一个很好的工具,可以将环境和主机隔离,避免破坏主机的环境,也便于跨机迁移。2.Conda 这是python环境管理的工具,也是进行环境隔离的,因为不同版本的python依赖的库版本差异比较大。通过conda能够很好的管理不同版本的python环境。3.网络知识
4.远程工具
3 总结
洋洋洒洒的写了这么多,还是比较粗糙,不过大部分都已经讲到了,其实并不是都需要去学习,还是看自己对哪方面感兴趣再详细系统的去学习,我学的都比较粗浅,有什么问题可以留言一起讨论,如果有能帮到你还请用你发财的小手点个赞+关注,感谢!