3. 相机-IMU标定(Kalibr)

相机-IMU标定(Kalibr) 学习卡片

任务目标

使用Kalibr工具完成相机内参标定与相机-IMU外参标定,最终生成包含相机内参、畸变系数、相机-IMU旋转与平移外参的YAML标定文件,供VINS-Fusion等视觉惯性SLAM系统直接使用。

环境与依赖

  • Ubuntu 16.04/18.04/20.04 + ROS(Kinetic/Melodic/Noetic均可)
  • Kalibr源码(github.com/ethz-asl/kalibr,按官方README编译安装)
  • 标定板:Aprilgrid 6x6(打印后贴平板),或棋盘格/圆点格
  • IMU:需能发布ROS的sensor_msgs/Imu消息
  • 相机:需能发布ROS的sensor_msgs/Image消息

标定流程概览

  1. 录制相机与IMU同步数据bag(相机30Hz左右,IMU 100-200Hz,时长约1-2分钟)
  2. 使用Kalibr对相机单独标定内参(可选,若已有内参可跳过)
  3. 使用Kalibr联合标定相机-IMU外参
  4. 验证标定结果并生成最终配置

第一步:录制标定数据

将标定板固定在墙上,手持相机-IMU组合件在标定板前缓慢运动,包含以下动作:绕X/Y/Z轴各旋转约±30°,平移扫过标定板平面,每个动作持续5-10秒。录制bag文件:

rosbag record -O calib_data.bag /camera/image_raw /imu/data

确保录制过程中标定板始终在相机视野内,且图像清晰无运动模糊。录制时长建议60-120秒。

第二步:相机内参标定(可选)

若相机内参未知,先单独标定。创建相机标定配置cam_april.yaml:

# 相机模型: pinhole-equi / pinhole-radtan / omni-radtan 等
cam0:
  camera_model: pinhole
  distortion_model: radtan
  resolution: [640, 480]
  rostopic: /camera/image_raw
  lens_hfov: 60.0  # 近似水平视场角,用于初始化

运行内参标定:

kalibr_calibrate_cameras --target april_6x6.yaml --bag calib_data.bag --models pinhole-radtan --topics /camera/image_raw

其中april_6x6.yaml为标定板描述文件(Kalibr提供模板,位于kalibr/config/目录)。标定完成后生成camchain-calib_data.yaml,包含相机内参与畸变系数。

第三步:相机-IMU外参标定

创建IMU配置imu.yaml:

# IMU噪声参数(可从IMU数据手册获取,或使用kalibr_imu_convert工具估算)
imu0:
  rostopic: /imu/data
  update_rate: 200.0  # IMU实际频率
  accelerometer_noise_density: 0.0002
  accelerometer_random_walk: 0.00002
  gyroscope_noise_density: 0.0001
  gyroscope_random_walk: 0.00001

运行联合标定(若已标定内参,使用生成的camchain文件):

kalibr_calibrate_imu_camera \
  --target april_6x6.yaml \
  --cam camchain-calib_data.yaml \
  --imu imu.yaml \
  --bag calib_data.bag \
  --timeoffset-padding 0.02

标定完成后生成三个文件:camchain-imucam-calib_data.yaml(相机内参)、imu-camchain-imucam-calib_data.yaml(IMU内参)、results-imucam-calib_data.txt(标定结果报告)。

第四步:提取外参并生成VINS配置

从标定结果文件中提取相机-IMU外参。打开results-imucam-calib_data.txt,找到类似以下内容:

Calibration results
===================
...
T_ci (imu to cam):
  - [0.0148, -0.9998, 0.0121, 0.0321]
  - [0.9997, 0.0149, 0.0182, -0.0045]
  - [-0.0184, -0.0118, 0.9998, 0.0112]
  - [0.0, 0.0, 0.0, 1.0]
...
timeshift cam to imu: 0.0123

其中T_ci为相机到IMU的变换矩阵(4x4),前三列为旋转矩阵R,第四列为平移向量t。将其转换为VINS-Fusion所需的四元数与平移向量格式,写入VINS配置文件cam_imu_calib.yaml:

# VINS-Fusion 相机-IMU外参配置
body_T_cam0:
  - [0.0148, -0.9998, 0.0121, 0.0321]
  - [0.9997, 0.0149, 0.0182, -0.0045]
  - [-0.0184, -0.0118, 0.9998, 0.0112]
  - [0.0, 0.0, 0.0, 1.0]
# 若需四元数形式,使用以下转换:
# q_ci = R2quat(R)  # 旋转矩阵转四元数
# p_ci = t          # 平移向量

验证方法

  1. 重投影误差检查:标定完成后,Kalibr会输出重投影误差(reprojection error)。若误差小于0.5像素,说明内参标定质量良好;若大于1像素,需重新录制数据或检查标定板检测情况。
  2. 外参合理性检查:查看results-imucam-calib_data.txt中的旋转矩阵,应接近单位矩阵(若相机与IMU近似同向安装);平移向量数值应与实际物理安装尺寸一致(单位:米)。
  3. 时间偏移检查:标定结果中的timeshift值应在±0.05秒范围内,若超出需检查数据同步或重新录制。
  4. VINS-Fusion实际运行验证:将生成的标定文件配置到VINS-Fusion中,运行视觉惯性里程计。若初始化成功且轨迹平滑无漂移,说明标定结果可用。

常见问题

  • 标定失败/优化不收敛:检查标定板是否完整出现在视野中、图像是否清晰、IMU数据频率是否准确、运动是否充分激励所有轴。
  • 重投影误差过大:可能是标定板打印不平整、相机分辨率设置错误或畸变模型选择不当。
  • 外参结果跳变:多次标定结果差异大,说明数据激励不足,需增加旋转运动并确保标定板始终可见。