3、多模态数据预处理:图像去畸变与校正、点云滤波与降采样、时间戳同步与空间对齐(外参标定基础)
各位同学,欢迎来到第三章。
上一章我们聊了BEV感知的整体架构,很多同学跃跃欲试,想直接上模型。别急,数据预处理这关过不了,后面全是白搭。我见过太多项目,模型结构改得花里胡哨,结果因为图像没校正、点云没对齐,最终精度就是上不去。
说白了,多模态融合的第一步,不是算法,是“对齐”。
3.1 图像去畸变与校正
摄像头拍出来的照片,天生就是变形的。尤其是鱼眼镜头,边缘的楼房都是弯的。你想想看,如果拿这种图去跟激光雷达的点云做融合,那位置肯定对不上。
畸变的来源主要有两种:
- 径向畸变:光线通过透镜时,边缘弯曲得厉害。说白了就是“桶形”或“枕形”变形。
- 切向畸变:镜头和成像平面不平行,导致图像倾斜。这个在量产车上比较常见,因为装配公差很难避免。
去畸变的原理其实不复杂。我们用一个数学模型来描述畸变:
// 径向畸变模型
x_distorted = x * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
y_distorted = y * (1 + k1 * r^2 + k2 * r^4 + k3 * r^6)
// 切向畸变模型
x_distorted = x + [2 * p1 * x * y + p2 * (r^2 + 2 * x^2)]
y_distorted = y + [p1 * (r^2 + 2 * y^2) + 2 * p2 * x * y]
其中 k1、k2、k3 是径向畸变系数,p1、p2 是切向畸变系数。这些参数需要通过标定得到。
校正完成后,图像就变成了“针孔模型”下的理想图像。这时候,像素点和真实世界的对应关系才是线性的。
3.2 点云滤波与降采样
激光雷达一秒钟能扫几十万甚至上百万个点。这么多点,直接扔给模型,计算量太大了。而且很多点是噪声,比如地面上的灰尘、空气中的雨滴。
点云滤波,说白了就是“去噪”。常用的方法有:
- 直通滤波:根据距离、高度、角度直接切掉。比如我只关心前方50米内的障碍物,那50米以外的点直接扔掉。
- 统计滤波:计算每个点周围邻居的平均距离,如果某个点离邻居太远,就认为是离群点,删掉。这个对去除“飞点”特别有效。
- 半径滤波:设定一个半径,如果这个半径内点数太少,就删掉。适合去除稀疏的噪声点。
降采样,则是为了减少数据量。最常用的是体素滤波(Voxel Grid Filter):
// 体素滤波伪代码
1. 设定体素大小,比如 (0.1m, 0.1m, 0.1m)
2. 将点云空间划分成一个个小立方体
3. 每个立方体内,只保留一个点(通常是重心点或中心点)
4. 其他点全部丢弃
嗯,这里还要提一句。点云滤波和降采样的顺序,我建议先滤波后降采样。因为噪声点如果不先去掉,降采样时可能会把噪声点当成“代表点”保留下来,那就尴尬了。
3.3 时间戳同步
摄像头和激光雷达的采集频率不一样。摄像头通常是20-30fps,激光雷达是10-20fps。而且,它们触发采集的时刻也不一样。
你想想看,如果图像是t1时刻拍的,点云是t2时刻扫的,而车在这段时间里移动了,那融合出来的结果肯定是“重影”的。
时间戳同步,就是要解决这个问题。常见做法有两种:
- 硬同步:通过硬件触发信号,让摄像头和激光雷达在同一时刻开始采集。这个精度最高,但需要硬件支持。
- 软同步:在软件层面,找到时间戳最接近的图像和点云帧,然后做插值或补偿。
软同步的代码实现大致如下:
def sync_sensor_data(image_list, lidar_list, max_time_diff=0.05):
"""
image_list: [(timestamp, image), ...]
lidar_list: [(timestamp, pointcloud), ...]
"""
synced_pairs = []
i, j = 0, 0
while i < len(image_list) and j < len(lidar_list):
img_ts = image_list[i][0]
lidar_ts = lidar_list[j][0]
diff = abs(img_ts - lidar_ts)
if diff < max_time_diff:
synced_pairs.append((image_list[i], lidar_list[j]))
i += 1
j += 1
elif img_ts < lidar_ts:
i += 1
else:
j += 1
return synced_pairs
3.4 空间对齐与外参标定基础
时间对齐了,空间还没对齐。摄像头看到的是像素坐标,激光雷达看到的是三维空间坐标。要把它们融合,就得知道摄像头和激光雷达之间的相对位置和姿态。
这个相对关系,就是外参。外参包括:
- 旋转矩阵 R:3x3的矩阵,描述两个传感器之间的旋转关系。
- 平移向量 t:3x1的向量,描述两个传感器之间的位移。
空间对齐的公式很简单:
// 将激光雷达点云投影到图像平面
1. 将点云从激光雷达坐标系转换到摄像头坐标系:
P_cam = R * P_lidar + t
2. 将摄像头坐标系下的点投影到图像平面:
u = f_x * (x_cam / z_cam) + c_x
v = f_y * (y_cam / z_cam) + c_y
其中 f_x、f_y 是摄像头内参,c_x、c_y 是主点坐标。
外参标定,就是求解 R 和 t 的过程。常用的方法有:
- 靶标法:在场景中放置标定板(如棋盘格),同时被摄像头和激光雷达看到。然后通过匹配角点来求解外参。
- 手眼标定法:如果传感器安装在机械臂或可移动平台上,可以通过多次移动来求解。
- 在线标定:在车辆行驶过程中,利用场景中的特征(如车道线、杆状物)自动优化外参。
好了,这一章的内容就到这里。数据预处理虽然繁琐,但它是多模态融合的基石。下一章,我们会正式进入BEV特征提取环节,看看如何把图像和点云的特征统一到BEV空间中去。