了解一个事物最好的办法就是debug一遍其源码,类似于看本质。
Nuscenes中的Radar pointcloud格式:
共有18个特征,包括x,y,z,……。可以看到z默认是0,也就是说,radar只能探测到x,y坐标,没有z的信息的。
通过token读到pointsensor的信息
总览
Radar -> image 投影可以分为五次映射
1. radar坐标系 -> 车辆ego坐标系(radar外参)
radar相对于ego的旋转、平移变换,信息存储在pointsensor[‘calibrated_sensor_token’]中。
其中,旋转信息是以四元素的方式存储,需要调用下面函数先转换成旋转矩阵以便计算
pc变换前后(仅对18个特征的前三个做了变换):
2. ego坐标系 -> global坐标系(radar)
从pointsensor[‘ego_pose_token’]中获取雷达探测时刻小车相对于全局的pose
pc变换前后(仅对18个特征的前三个做了变换):
3. global坐标系 -> ego坐标系(相机外参)
从cam[‘ego_pose_token’]中获取相机拍摄时刻小车相对于全局的pose,注意,此处应是逆变换。由于:
若 A, B 均可逆,则 (AB)^(-1) = B^(-1) A^(-1)
所以先平移后旋转,并且都是原矩阵的逆矩阵(注:其中旋转矩阵为正交矩阵其逆等于其转置)。
pc变换前后(仅对18个特征的前三个做了变换):
4. ego坐标系 -> camera坐标系
从cam[‘calibrated_sensor_token’]中获取相机拍摄时刻相机外参,即旋转平移参数(注意,cs_record中还包括内参,第五步将用到)
pc变换前后(仅对18个特征的前三个做了变换):
5. camera坐标系 -> image坐标系 (相机内参)
从cs_record[‘camera_intrinsic’]中获取相机内参
将pc投影至image平面,注意,由于投影后会损失一个维度的信息(深度),因此额外保存该通道信息
pc变换前后:
保留的深度信息:
最终结果:
一个思考:
为什么要多做一步投影到global坐标系下?
因为camera和radar并不是同时触发的,其时间戳存在一定延迟,在这一小段延迟中,车辆可能已经行驶了小段路程,要把这个作为传感器运动的补偿考虑进去。当然,我们默认两份数据中感知到的环境在小段时间内变化不大。
如果车辆是完全静止,两个状态小车完全重叠,就不需要投影到global坐标系下。
————————————————————————————————————————————
nuscenes源码