4、传感器标定:Camera内参标定、Camera-Lidar联合标定、标定工具(Kalibr/Livox_Calibration)使用

说到传感器标定,我脑子里第一个蹦出来的词就是「对齐」。说白了,就是把摄像头看到的像素和激光雷达打到的点云,在空间上拧到一起去。这件事做不好,后面所有的融合算法都是空中楼阁。我在项目里见过太多团队,算法调了几个月效果还是差,最后发现是标定参数偏了那么零点几度——嗯,这种坑我踩过不止一次。

4.1 Camera内参标定:先把眼睛的度数配准

摄像头内参标定,其实就是搞清楚镜头本身的畸变和焦距。你想想看,一个广角镜头拍出来的画面边缘都是弯的,不矫正的话,你拿像素坐标去算物理距离,那误差能大到离谱。

我个人习惯用棋盘格标定板,打印出来贴在平板上,然后从不同角度拍个二三十张照片。这里有个关键点:标定板一定要平整。我曾经有一次偷懒,用海报纸打印的棋盘格,结果标定出来的焦距参数总是飘,后来才发现是纸面有褶皱。

核心步骤:

  1. 采集多角度棋盘格图像(20-30张)
  2. 检测角点亚像素坐标
  3. 求解内参矩阵 K 和畸变系数
  4. 重投影误差评估(一般要求 < 0.5 pixel)

常用的工具是 OpenCV 的 calibrateCamera() 函数。不过我个人更推荐用 Kalibr 来做,因为它能同时标定多个相机,而且支持鱼眼模型。代码大概长这样:

# 使用 Kalibr 进行单目内参标定
kalibr_calibrate_cameras \
    --target april_6x6.yaml \
    --models pinhole-radtan \
    --cams cam0.yaml \
    --bag calibration.bag

这里要注意,--target 文件里要定义标定板的尺寸和类型。我习惯用 Aprilgrid,因为它比棋盘格更鲁棒,部分遮挡也不影响检测。

我的小技巧:标定的时候,让标定板尽量充满画面各个区域,尤其是四个角落。这样畸变参数才能被充分约束。我一般会拍一组「绕圈」的视频,然后抽帧使用。

4.2 Camera-Lidar联合标定:让眼睛和耳朵对齐

Camera 和 Lidar 的联合标定,说白了就是求一个旋转平移矩阵,把激光雷达的点云投影到图像平面上。这件事的难点在于:两个传感器的数据模态完全不同——图像是稠密的纹理信息,点云是稀疏的几何信息。

我记得第一次做联合标定时,投影出来的点云总是偏半个车身。查了两天,最后发现是 Lidar 的安装角度标错了。所以我现在做联合标定,一定会先确认两个传感器的「硬同步」——时间戳对齐了,空间标定才有意义。

4.2.1 标定原理

联合标定的目标就是求解一个 4x4 的变换矩阵 T_cam_lidar:

P_image = K * T_cam_lidar * P_lidar

其中 P_lidar 是激光雷达坐标系下的点,K 是之前标好的内参矩阵。说白了,就是把 Lidar 的点先转到相机坐标系下,再用内参投影到像素平面。

4.2.2 标定流程

我常用的方法是找一些「角点对应」——在点云里找一个反射板的角点,同时在图像里找到对应的像素坐标。至少需要 4 组对应点才能解出变换矩阵。实际操作中,我会用标定板上的棋盘格角点作为桥梁:

  1. 在标定板周围采集 10-15 帧同步数据
  2. 手动或自动提取图像中的棋盘格角点
  3. 在点云中提取标定板平面的点云,拟合平面后计算角点位置
  4. 用 PnP 算法求解 T_cam_lidar

避坑指南:我曾经在户外做标定,阳光太强导致 Lidar 的反射板回波信号弱,点云里根本看不到标定板。后来我改用高反光材料(比如 3M 钻石级反光膜),效果好了很多。另外,标定环境最好选在室内或者阴天,避免阳光直射 Lidar。

4.3 标定工具:Kalibr 与 Livox_Calibration

工具这块,我主要用两个:Kalibr 和 Livox_Calibration。它们各有侧重,我分别说说。

4.3.1 Kalibr:多传感器标定的瑞士军刀

Kalibr 是 ETH Zurich 开源的标定工具,支持 Camera 内参、Camera-IMU、多 Camera 联合标定。它的核心优势是:基于连续时间轨迹的优化方法,能同时估计传感器内参和外参,而且对时间偏移也很敏感。

使用 Kalibr 的典型流程:

# 1. 制作标定板配置文件
cat > april_6x6.yaml << EOF
target_type: 'aprilgrid'
tagCols: 6
tagRows: 6
tagSize: 0.088
tagSpacing: 0.3
EOF

# 2. 运行标定
kalibr_calibrate_cameras \
    --bag data.bag \
    --topics /camera/image_raw \
    --models pinhole-equi \
    --target april_6x6.yaml

# 3. 联合标定 Camera-Lidar
kalibr_calibrate_cameras_lidar \
    --bag data.bag \
    --cam camchain.yaml \
    --lidar lidar.yaml \
    --target april_6x6.yaml

我个人觉得 Kalibr 最大的坑是:对数据质量要求很高。如果标定过程中有抖动或者标定板移动太快,优化很容易发散。我一般会先跑一遍数据检查脚本,看看角点检测的稳定性。

4.3.2 Livox_Calibration:专为 Livox 激光雷达设计

如果你用的是 Livox 系列的激光雷达(比如 Horizon、Mid-40),那 Livox_Calibration 是首选。它由 Livox 官方维护,专门针对 Livox 的非重复扫描特性做了优化。

它的标定思路和 Kalibr 不太一样:利用点云中的平面特征和图像中的边缘特征进行配准。说白了,就是找点云里的平面和图像里的边缘线,让它们对齐。

# Livox_Calibration 使用示例
roslaunch livox_camera_calib calib.launch \
    camera_topic:=/camera/image_raw \
    lidar_topic:=/livox/lidar \
    chessboard_size:=0.108 \
    chessboard_corner_x:=11 \
    chessboard_corner_y:=8

我的经验:Livox_Calibration 对棋盘格的摆放角度很敏感。我试过把标定板倾斜 30 度左右,点云里的平面特征最明显,标定结果也最稳定。另外,它支持实时标定,你可以一边移动标定板一边看投影效果,非常直观。

4.4 标定结果验证:别信参数,信眼睛

标定完事后,一定要做验证。我习惯用两种方法:

  • 重投影误差检查:把点云投影到图像上,看边缘是否对齐。误差在 2-3 个像素以内算合格。
  • 距离验证:在 5m、10m、20m 处放置目标物,看投影位置是否准确。

我记得有一次标定结果重投影误差只有 1.2 像素,但实际跑起来就是偏。后来发现是 Lidar 的安装支架有微小的热变形——白天和晚上的温度差导致支架弯曲了 0.1 度。所以我现在做量产项目,都会在标定后加一个「温度补偿」环节。

总结一下标定的关键点:

  • 内参标定是基础,一定要做扎实
  • 联合标定需要好的特征对应,标定板是关键
  • 工具选型看传感器类型:Kalibr 通用性强,Livox_Calibration 专为 Livox 优化
  • 标定完成后必须做实际场景验证
传感器标定知识体系 传感器标定 Camera内参标定 Camera-Lidar联合标定 Kalibr工具 Livox_Calibration 棋盘格/Aprilgrid 角点检测 内参矩阵 K + 畸变系数 重投影误差 < 0.5 pixel 求解变换矩阵 T_cam_lidar PnP 算法 + 点云平面拟合 重投影误差 < 3 pixel 连续时间轨迹优化 支持多传感器联合标定 标定结果验证:重投影 + 距离验证 图:传感器标定知识体系结构图

好了,以上就是传感器标定的核心内容。内参标定是基础,联合标定是关键,工具选型看场景。我个人建议:标定这件事,宁可多花一天时间做验证,也不要省那半小时——因为后面所有的感知算法,都建立在这套参数之上。

可可精品资料库