
标定这件事几乎每个做多传感器融合的人都躲不开。激光雷达和相机各说各话点云在三维空间里描述世界图像在二维平面上记录光影两边都对但坐标系对不上后面的目标检测和感知融合就全是白搭。livox_camera_calib就是解决这个对齐问题的开源工具它主要面向Livox系列激光雷达与普通相机的联合外参标定能把雷达坐标系和相机坐标系之间的旋转和平移关系算出来让点云能准确投影到图像上。适合谁看如果你是做自动驾驶、机器人导航、SLAM建图或者测绘项目手头刚好有Livox雷达和工业相机这个工具能帮你少走不少弯路。我下面写的这套流程是从零开始的完整实操覆盖环境搭建、数据采集、标定运行到结果验证最后还整理了我在多个项目里踩过的坑。建议你收藏了到时候对着一步步做。1. 标定的底层逻辑为什么两套传感器需要对齐1.1 齐次变换矩阵与坐标系关系激光雷达输出的是三维点云每个点用(x, y, z)表示基准是雷达自己的坐标系。相机输出的是图像像素坐标(u, v)描述的是光线经过镜头后落在感光元件上的位置。两者描述的是同一个物理世界但因为安装位置和朝向不同同一个物体在两边的坐标完全不一样。联合标定要干的事就是求一个4x4的齐次变换矩阵把雷达点云从雷达坐标系转换到相机坐标系再经过相机内参投影到像素平面。这个矩阵由旋转矩阵R和平移向量t组成外参标定本质上就是求解R和t的最优值。很多人会问直接用尺子量安装位置不行吗当然不行。雷达和相机之间的安装角度哪怕差1度在20米外就会产生几十厘米的投影误差对感知系统来说直接是灾难。手工测量无法达到传感器融合需要的精度必须通过算法利用标定板的几何约束来优化求解。这也是为什么所有正经的传感器标定方案走的都是特征提取加非线性优化的路线而不是拿卷尺量。1.2 livox_camera_calib的核心思路这个工具的思路其实很巧妙。它不依赖雷达反射强度或者特殊的发光标记而是利用标定板这个平面物体做桥梁。在相机图像里标定板的角点可以被准确提取出来在雷达点云里标定板的点云落在同一个平面上而且扫描到标定板边缘时会产生密集的点线特征。工具通过提取图像角点和点云平面边缘建立对应关系再用Ceres Solver这个非线性优化库去迭代求解外参。这种方案的最大优势是不需要雷达和相机在硬件上严格同步曝光也不要求标定板有特殊材质。只要标定板有一定尺寸、表面平整、在点云中形成清晰的平面轮廓算法就能工作。对普通项目和量产调试来说这已经是效率很高、门槛很低的路线了。比起那种需要在特定暗室、用特定光源配合的标定方法这套流程在室外和普通室内环境都能跑。1.3 工具适配范围与适用场景livox_camera_calib官方的适配对象是Livox系列雷达包括Mid-40、Mid-70、Horizon、Avia、Mid-360等常见型号主要跑在ROS 1环境下。相机端没有太严格的限制普通USB相机、工业相机、甚至一些自带畸变校正的广角相机都可以用前提是你已经标定好了相机内参。适用场景包括自动驾驶测试车、巡检机器人、测绘无人机地面站、室内AGV等只要需要把点云和图像融合显示的场合基本都会用到这一环节。这里提醒一句如果手头是非Livox的机械式雷达比如Velodyne或者国产16线雷达这个工具的算法并不直接支持但可以借鉴它的标定板选点和优化思路配合其他开源方案来做这个我在后面避坑部分会展开讲。如果你刚开始接触这个工具建议先把Livox雷达跑通再考虑扩展移植。2. 环境准备先把这道坎迈过去2.1 系统与ROS版本选择我先后在Ubuntu 16.04加ROS Kinetic、Ubuntu 18.04加ROS Melodic、Ubuntu 20.04加ROS Noetic上都跑通过这套工具。官方文档最早推荐16.04和Kinetic但如果用更新的环境也没有问题关键是依赖库版本要对。实际项目里我建议优先用Ubuntu 18.04加ROS Melodic这个组合网上资源最多遇到问题容易搜到答案。如果你已经在用Noetic也能跑通只是在编译OpenCV和Ceres时会遇到一些版本相关的坑后面踩坑部分我有具体说明。另外强调一点这套工具依赖的是ROS 1不是ROS 2。虽然Livox官方后来推出了ROS 2版本的驱动但livox_camera_calib的主仓库目前依然是ROS 1。别一上来就建ROS 2工作空间那样会浪费不少时间。如果是想搭配cartographer做建图也建议在ROS 1里先把标定做完再考虑后续迁移。2.2 依赖库清单与安装方法需要装的依赖有PCL点云库、OpenCV、Eigen、Ceres Solver还有Livox雷达驱动livox_ros_driver。前三个有些是ROS自带或者系统中已有的Ceres Solver一般需要自己编译这是最容易出问题的环节。Ceres Solver的编译我建议用源码方式。网上很多教程直接用apt安装旧版本版本过老会导致编译失败。源码编译步骤不复杂git clone https://github.com/ceres-solver/ceres-solver.git cd ceres-solver mkdir build cd build cmake .. make -j8 sudo make install编译之前需要确认系统里有gflags、glog、suitesparse这些依赖缺了会在cmake阶段直接报错。在Ubuntu 18.04上可以这样安装sudo apt-get install libgoogle-glog-dev libgflags-dev libatlas-base-dev libsuitesparse-devlivox_ros_driver也需要提前装好这个驱动装完可以直接用雷达的ROS驱动节点采集标定数据时会用到。把驱动clone到工作空间的src目录下catkin_make之后source一下环境变量即可。装完可以先启动驱动试一下看雷达点云能不能正常显示确认雷达IP和网段配置没问题再继续。2.3 源码编译的完整指令把livox_camera_calib代码放进工作空间并编译指令如下mkdir -p ~/calib_ws/src cd ~/calib_ws/src git clone https://github.com/Livox-SDK/livox_camera_calib.git git clone https://github.com/Livox-SDK/livox_ros_driver.git cd ~/calib_ws catkin_make source devel/setup.bash编译过程中常见的问题基本都集中在找不到OpenCV头文件、找不到Ceres库、Eigen版本冲突这三类。遇到这类问题先确认环境变量和库路径再回头看版本。我个人习惯是把Ceres、PCL、OpenCV相关的cmake路径写在~/.bashrc里防止新终端找不到。这里多说一句如果你用的雷达型号是Mid-360注意驱动版本要匹配有些老版本驱动对新固件适配不好会导致点云数据异常这个问题在标定前一定要排除掉否则后面采集的数据全是废的。3. 数据采集外参精度七分靠采集3.1 标定板的尺寸与制作细节标定板是整个标定流程的视觉基准重要性远超很多人的想象。官方推荐的标定板是黑白棋盘格图案尺寸不能太小我建议至少1.2米乘0.9米格子边长8到10厘米。太小的板子在雷达点云中投影的点数太少平面拟合不稳定角点提取也容易失败太大的板子在室外搬运不方便因此室内项目选1.5米见方左右室外项目选1米见方加硬质底板。制作时千万不要用普通A4纸打印贴在纸板上因为纸板容易弯曲相机图像里角点检测没问题但雷达点云拟合出来的平面和图像里的平面不在同一个几何平面上标定结果会出现系统性偏差。正确做法是打印在硬质PVC板或者铝塑板上也可以用亚克力板背面贴黑白格确保整个板面平整不变形。如果有条件可以在标定板四周加白色边框方便在点云中识别边界。3.2 传感器固定与时间同步雷达和相机必须刚性固定在采集过程中绝对不能有相对位移。如果你用螺丝固定在同一个支架上要确认所有螺丝拧紧如果用了胶带或者快拆结构建议先做一次振动测试。标定过程中传感器任何微小的抖动都会被优化算法放大成外参误差。时间同步方面livox_camera_calib并不要求雷达和相机做硬件触发同步但至少要保证数据是同一时间段采集的。实际操作中建议同时启动雷达驱动和相机节点先预跑几秒让传感器稳定再开始记录数据。如果你使用ROS bag录制录制前后不要移动标定板这样能保证图像和点云的时间戳差不会造成明显的位姿变化。Livox雷达连接上之后还有一个容易忽略的点就是IP配置。不同型号的Livox雷达默认IP不一样Mid系列常见的出厂IP是192.168.1.1xxHorizon可能是192.168.1.12x具体需要查官方文档。电脑网卡要设置到同一个网段才能被livox_ros_driver正常发现。这个步骤没做对驱动启动后话题里一直收不到点云后面什么都干不了。3.3 采集位置与姿态规划这一步直接决定标定能否成功。采集时标定板要放在雷达和相机共同视场范围内离传感器太近会导致点云密度过高但角点容易截断太远则点云稀疏我建议距离在3到8米之间。标定板的姿态要多变要覆盖正面、左偏、右偏、上仰、下俯这五个角度每个角度至少让标定板在图像中占比超过三分之一。采集过程中要尽量让标定板静止。手持标定板晃动会导致点云边缘模糊后期特征提取时会刷掉不少有效点。最好的方式是使用三脚架或支架固定标定板每换一个姿态拍一组数据。如果条件不允许手持也勉强能用但手臂一定要撑住保持稳定2到3秒再记录。采集数据时可以直接用rosbag录制命令大致如下rosbag record -O calib_data /livox/lidar /camera/image_raw录制时每个姿态停留两三秒不用频繁启停一气呵成录完后面再离线截取有效片段就行。采集完一组数据后建议先快速检查一下图像里标定板是否清晰完整点云里对应区域能不能看到明显的平板轮廓。如果点云里压根看不到标定板那就是距离太远或者角度太偏需要调整位置重新拍。4. 标定实操从配置到出结果4.1 配置文件逐项解读livox_camera_calib的配置文件在config目录下是一个YAML文件里面主要包含相机内参、畸变系数、标定板尺寸和点云稀疏化参数。大致结构类似这样camera: fx: 615.0 fy: 615.0 cx: 320.0 cy: 240.0 k1: -0.2 k2: 0.05 p1: 0.0 p2: 0.0 k3: 0.0 chessboard: width: 9 height: 6 size: 0.1不同版本字段名可能略有差异以你clone下来的源码里的示例为准。相机内参需要提前用张正友标定法或者其他工具标定好填进去的时候要注意fx、fy、cx、cy的单位是像素畸变系数顺序按照OpenCV的k1、k2、p1、p2、k3来填顺序千万不要弄错。标定板尺寸方面要填写的是黑白格的角点数量比如水平方向9个角点、垂直方向6个角点以及每个小格的实际边长单位是米。这个尺寸填错的话优化算法求解出来的尺度会不对投影验证时偏移量会非常大。点云稀疏化参数用于控制参与优化的点云密度。如果你用的是Mid-360这类非重复扫描雷达点云密度比较高建议适当降采样既提升计算速度又能降低噪声点的影响。这个参数我一般设在0.05到0.1之间具体要看现场环境。4.2 启动标定节点与特征提取配置完成后先启动雷达驱动和相机驱动确保rostopic里能看到图像话题和点云话题。然后用launch文件启动标定节点roslaunch livox_camera_calib calib.launch启动后标定节点会订阅图像和点云话题。如果配置正确运行日志会显示成功加载相机内参和标定板参数。此时程序会自动在当前图像中检索标定板角点并在点云中搜索标定板平面。你可以通过可视化窗口观察角点是否准确落在黑白格交叉点上点云平面的拟合是否符合预期。这一步经常出现两个现象一是图像角点检测失败原因是光照不均匀或者标定板遮挡二是点云平面提取失败原因是标定板距离太远或姿态太极端。遇到失败时调整标定板位置重新采集不要试图调整参数硬跑。硬跑出来的结果往往看着收敛了一投影验证就露馅。4.3 优化求解与结果输出当图像和点云特征都提取成功后程序会进入优化阶段。Ceres Solver会通过最小化重投影误差来迭代求解R和t。这个过程通常只需要几秒到十几秒控制台上会输出每次迭代的代价函数值。如果代价函数持续下降并最终收敛到较小值说明优化正常如果代价函数震荡或者不下降大概率是初始值设置有问题或者数据质量差。优化完成后工具会生成标定结果文件里面包含旋转矩阵和平移向量。此时不要急着用先做投影验证。用标定后的外参把雷达点云投影到图像上观察点云轮廓和图像边缘是否贴合。如果所有标定板位置的投影误差都小于几个像素说明标定质量很好。如果投影点偏移明显需要重新采集或检查配置。4.4 多帧标定与初始值设置官方工具还支持用多帧标定数据联合优化。每一帧数据都提取一组特征然后放到同一个优化问题中求解。多帧联合优化的好处是可以减少单帧的偶然误差但代价是每一帧都要有足够好的特征提取结果。我建议至少采集5组以上不同姿态的数据覆盖范围越广外参在视场边缘的准确性越好。初始外参的设定也很重要。即使优化算法能自行收敛好的初始值能显著提升收敛速度和稳定性。一般可以先按安装位置粗略测量写一个大概的R和t作为初始值。测量精度不需要很高但方向别搞反尤其是旋转矩阵的符号否则优化会把外参收敛到一个错误的局部最优解上。如果发现优化结果反复横跳先回头检查初始值是不是给得太离谱了。5. 避坑指南与常见问题实录5.1 我踩过的那些坑第一个坑是Ceres版本问题。有段时间我图省事直接apt装了一个旧版Ceres结果编译livox_camera_calib时报了一堆模板相关的错误排查了半天。后来换成源码编译最新稳定版问题立刻消失。建议所有依赖库都用源码编译不要偷懒用系统源版本差异是最容易埋雷的地方。第二个坑是OpenCV的接口变化。在Ubuntu 20.04加ROS Noetic环境下系统自带的是OpenCV 4跟工具早期版本依赖的OpenCV 3 API存在不兼容。编译时可以通过修改CMakeLists指定OpenCV的版本路径或者干脆在18.04环境里跑省心很多。我自己后来固定用18.04环境做标定基本一次通过。第三个坑是相机畸变参数顺序填错。工具读取畸变系数时如果你把OpenCV标定结果直接复制过去顺序很可能对不上导致角点提取后去畸变出错优化出来的外参明显偏差。解决方法是仔细看工具源码里读取畸变的顺序再对照自己标定结果的存储顺序做调整。我当时是打印出来逐个字段对比才找到问题所在。5.2 常见问题速查表问题现象可能原因解决方案编译报找不到CeresCeres未安装或路径未配置源码编译Ceres并设置CMAKE_PREFIX_PATH图像角点检测不到光照过强或标定板太小调整采集角度增大标定板尺寸均匀补光点云中找不到标定板平面标定板距离过远或姿态过偏把标定板移到3到8米范围内姿态不要超过45度优化代价函数不收敛初始外参偏差过大提供更准确的初始R和t或增加高质量数据帧投影验证时整体偏移相机内参错误或畸变顺序不对重新标定相机内参检查畸变系数顺序雷达点云在图像上整体旋转外参旋转矩阵符号错误检查R的符号调整初始旋转设置雷达启动后无点云话题IP配置错误或网线未连接检查雷达IP与电脑网段使用Livox Viewer确认连接5.3 提升标定精度的几条实战经验第一个经验是光线。室外标定尽量选择阴天或者早上傍晚阳光直射会在标定板上产生高光和阴影角点检测很容易失败。室内标定使用均匀光源避免单侧强光。我在一个项目里因为现场天花板灯管造成不均匀反光连续三组数据角点都检测不全换了一个漫反射光源后一次性通过。第二个经验是镜头焦距的选择。标定用的相机最好用固定焦距镜头不要用自动变焦或者自动光圈。如果相机有自动曝光功能建议改成手动曝光固定曝光时间和增益这样不同姿态下标定板的亮度和对比度一致角点提取更稳定。很多USB摄像头默认开了自动曝光采样时亮度忽明忽暗这个细节特别影响效果。第三个经验是雷达混合像素问题。Livox雷达在扫描到物体边缘时会产生介于前景和背景之间的混合点这些点会对平面拟合造成干扰。在点云预处理时可以通过距离阈值把远离标定板的点剔除掉只保留标定板附近0.5米范围内的点云参与拟合这样平面参数会更干净。这也是解决建图飘逸的一个排查方向很多乍一看像是SLAM算法的问题溯源起来其实是外参不准确导致的误差累积。6. 标定结果的验证与后续扩展6.1 投影验证的具体操作标定完不是看到一组数字就完事了必须做投影验证。把标定后的外参发布出去在rviz中显示点云同时把相机图像作为底图叠加观察标定板的点云边缘是否精确落在图像的边缘上。如果没有现成的可视化节点可以写一个简单的ROS节点订阅image和pointcloud话题把点云投影到图像坐标系并在图像上画点这样最直观。验证时重点关注不同距离下的对齐效果。近处1到2米对齐得很好远处10米就漂了说明外参的旋转矩阵可能还有小误差所有距离都往同一个方向偏移说明平移向量可能偏大或偏小。针对不同现象可以回退调整后再优化。我一般会选三个距离档位各放一次标定板分别看投影偏差这样能快速判断误差来自旋转还是平移。6.2 标定结果如何应用到感知系统拿到外参之后接下来的用法就多了。最常见的是把雷达点云投影到图像上做目标级融合比如在图像检测框上叠加点云深度信息或者把点云聚类结果映射到图像上。也有一些方案倒过来把图像语义分割结果映射到三维空间为点云着色或者增强特征。不管怎么用都要注意外参是在特定传感器安装状态下标定的。如果雷达或相机拆装过、碰撞过或者支架有变形必须重新标定不要沿用旧参数。项目现场如果可能经常拆装建议把标定流程固化成脚本连标定板也固定收纳需要时两小时就能重新走完一遍。后续做ROS 2加cartographer建图的时候也别忘了把标定外参同步过去两个系统用的坐标关系不一致会导致地图和图像对不上。6.3 非Livox雷达的移植思路如果你用的不是Livox雷达这个工具虽然不能直接用但思路完全可以借鉴。核心就是利用平面标定板在图像上提取角点在点云中拟合平面然后建立3D到2D对应关系用PnP或者非线性优化求解外参。这个思路已经被很多开源项目验证过比如autoware的标定工具、一些基于ArUco的标定方案大概率能满足大多数项目需求。我在实际项目里有一个客户用的是国产16线机械雷达没法跑livox_camera_calib我就把它的角点检测和平面拟合拆出来换了自己的点云预处理最后用OpenCV的solvePnP也把外参算出来了精度满足项目要求。所以说工具是死的思路是活的理解原理比死记命令更重要。就算以后换了传感器型号这套标定板的选点思路和优化套路依然能复用。说实话标定这件事看着简单真正上手以后才会发现细节决定成败。我个人最大的体会是八分靠采集两分靠优化算法。数据采集时多花半小时把标定板姿态和光线条件都安排好后面优化求解几乎一路顺畅反过来数据采集要是太随意后面做多少次重优化都很难拿到可靠外参。所以动手标定之前建议先把环境和标定板准备好现场配合固定支架和多角度拍摄基本能做到一次成功。遇到问题也别慌按我上面整理的排查表逐项对照大多数情况都能快速定位到根源。祝各位顺利把点云和图像对齐少踩坑多出活。