1. 为什么需要激光雷达与相机联合标定当我们在做机器人导航、自动驾驶或者三维重建时经常会遇到一个关键问题如何把激光雷达扫描到的点云数据和相机拍摄的彩色图像完美融合这个问题看似简单实际操作起来却有很多门道。想象一下你左手拿着激光雷达右手拿着相机同时观察同一个场景。激光雷达能告诉你每个物体离你有多远但不知道它是什么颜色相机能拍出漂亮的彩色照片却很难准确判断物体的距离。如果能把这二者的数据结合起来就能得到既有距离信息又有颜色信息的彩色点云这对环境感知来说简直是如虎添翼。但这里有个关键前提你必须知道激光雷达和相机之间的精确位置关系。这个关系就是我们要通过标定来确定的外参Extrinsic Parameters。具体来说就是一个4×4的变换矩阵包含了旋转和平移信息能把激光雷达坐标系下的点转换到相机坐标系下。我在实际项目中遇到过不少因为标定不准导致的坑。最典型的就是点云和图像对不齐明明是一堵墙点云却飘在图像中墙的前面或后面。这种误差在自动驾驶中尤其危险可能导致系统误判障碍物位置。所以掌握一套可靠的标定方法对SLAM和自动驾驶开发者来说至关重要。2. 准备工作与环境配置2.1 硬件准备清单工欲善其事必先利其器。我们先来看看需要准备哪些硬件设备3D激光雷达推荐使用Velodyne VLP-16性价比高或HDL-32E精度更高。我这次用的是VLP-16它的水平视场角360°垂直视场角30°最大测距约100米完全够用。RGB相机Realsense D435i是我的首选因为它自带IMU深度测量也相对准确。其他选择包括ZED相机或普通USB摄像头但要注意必须有ROS驱动支持。标定板材料A4纸打印ArUco二维码硬纸板快递箱拆下来的就行双面胶绳子用于悬挂标定板2.2 软件环境搭建软件方面我们需要以下组件# 基础ROS环境以Melodic为例 sudo apt-get install -y python-catkin-tools python-catkin-pkg python-rosdep sudo apt-get install -y ros-melodic-cv-bridge ros-melodic-image-transport sudo apt-get install -y ros-melodic-nodelet-core ros-melodic-ddynamic-reconfigure sudo apt-get install -y ros-melodic-velodyne-pointcloud # 标定工具包 cd ~/catkin_ws/src git clone https://github.com/ankitdhall/lidar_camera_calibration.git mv lidar_camera_calibration/dependencies/aruco_ros aruco_ros mv lidar_camera_calibration/dependencies/aruco_mapping aruco_mapping # 编译 cd ~/catkin_ws rosdep install --from-paths src --ignore-src -r -y catkin_make -DCATKIN_WHITELIST_PACKAGESaruco;aruco_ros;aruco_msgs catkin_make -DCATKIN_WHITELIST_PACKAGESaruco_mapping;lidar_camera_calibration这里有个常见坑点如果遇到raw.githubusercontent.com无法访问的问题不要慌。这是因为国内网络环境导致的可以通过修改hosts文件解决# 在/etc/hosts中添加 185.199.108.133 raw.githubusercontent.com3. 制作高精度标定板3.1 生成ArUco二维码标定板的核心是ArUco二维码这是一种专为计算机视觉设计的特殊标记。我推荐使用Online ArUco Marker Generator在线生成工具操作简单又免费。具体步骤选择字典类型DICT_6X6_250设置Marker ID建议用26和582与示例一致尺寸设为125mm×125mm这个尺寸实测效果最好下载PNG格式图片用A4纸打印注意两个Marker的ID必须不同且小的ID放在左边。打印时确保没有缩放实际尺寸必须精确。3.2 手工制作标定板打印好二维码后开始手工部分裁剪两块硬纸板建议30cm×40cm将二维码贴在纸板左上角边缘留出2cm空白用绳子将两块标定板悬挂起来间距约1米这里有个实用技巧悬挂时让两块板不在同一平面前后错开约30cm。这样能提供更好的深度信息标定结果会更准确。我刚开始做的时候两块板平行放置结果标定误差大了近30%。4. 参数配置详解4.1 修改launch文件关键文件是find_transform.launch位于lidar_camera_calibration/launch目录。需要修改以下参数node pkgaruco_mapping typearuco_mapping namearuco_mapping outputscreen remap from/image_raw to/camera/color/image_raw/ param namecalibration_file value$(find aruco_mapping)/data/zed_left_uurmi.ini/ param namenum_of_markers value2/ param namemarker_size value0.125/ !-- 单位米 -- param namespace_type valueplane/ /noderemap确保与你的相机话题一致marker_size必须与打印的二维码实际尺寸一致0.125米12.5厘米num_of_markers使用几个二维码我们用了2个4.2 相机内参配置相机内参可以通过棋盘格标定获取但有个偷懒的方法直接查看相机发布的camera_info话题rostopic echo /camera/color/camera_info将输出的内参矩阵填到zed_left_uurmi.ini文件中[image] width 640 height 480 [camera] fx 616.368 fy 616.745 cx 319.935 cy 243.6394.3 标定范围设置config_file.txt中的xyz范围决定了激光雷达会处理哪些点云数据。建议这样设置640 480 # 图像分辨率 -1.0 1.0 # x轴范围左负右正 -1.0 1.0 # y轴范围下负上正 0.5 3.0 # z轴范围前正后负 0.0005 # 点云强度阈值 2 # 标定板数量 1 # 是否使用相机内参话题这个设置表示只处理相机前方0.5~3米左右各1米范围内的点云。如果标定时看不到标定板边缘可以适当扩大范围或降低强度阈值。5. 标定流程实战5.1 启动标定程序一切就绪后运行roslaunch lidar_camera_calibration find_transform.launch正常情况下会弹出三个窗口相机图像带ArUco坐标系显示点云边缘检测结果标定过程可视化5.2 手动选取边缘点这是最关键也最容易出错的一步在点云窗口中找到标定板的四条边按顺时针方向用鼠标点击每条边的两个端点共8个点每点击一个点按空格确认先标定左边的板子再标定右边的实测技巧点击时尽量选边缘明显的点避免选拐角。如果点云太稀疏可以适当调低cloud_intensity_threshold。5.3 处理常见错误问题1相机检测不到二维码检查光照是否充足确保二维码尺寸设置正确尝试调整相机焦距问题2点云中看不到边缘调整标定板位置使其正对雷达降低强度阈值如从0.001调到0.0005检查雷达与标定板距离是否在设定范围内问题3标定结果发散确保两个标定板不在同一平面重新检查手动选取的点是否准确尝试交换两个标定板的选取顺序6. 结果验证与应用6.1 解读标定结果成功后会输出类似这样的变换矩阵Average rotation: [0.999, -0.012, 0.042; 0.013, 0.999, -0.009; -0.041, 0.010, 0.999] Average translation: [0.12, -0.05, 0.30] Final rotation: [0.998, -0.011, 0.045; 0.012, 0.999, -0.008; -0.045, 0.009, 0.998]注意实际使用时应该用Final rotation和Average translation组合成4×4变换矩阵。6.2 发布TF变换将标定结果转换为TF可以通过以下C代码实现tf::Transform transform; transform.setOrigin(tf::Vector3(0.12, -0.05, 0.30)); tf::Quaternion q; q.setRPY(0.045, -0.008, 0.012); // 注意旋转顺序 transform.setRotation(q); static tf::TransformBroadcaster br; br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), camera_color_optical_frame, velodyne));6.3 可视化验证在RViz中添加相机点云/camera/depth/color/points激光雷达点云/velodyne_points设置固定坐标系为velodyne如果标定准确两者的点云应该能完美重合。我通常会用墙角、桌缘等特征明显的物体做最后检查误差控制在2cm以内算合格。7. 工程实践中的经验分享经过多次标定实践我总结出几个提升精度的技巧标定板布局两个板子最好呈90°夹角放置这样能提供更丰富的空间约束。有次我把两个板子平行放置结果Z轴方向的标定误差明显增大。环境光线避免强光直射标定板否则相机可能检测不到二维码。阴天室内自然光是最理想的条件。运动干扰标定过程中雷达和相机必须保持绝对静止。有次旁边有人走过引起振动导致标定失败。多次平均建议进行3-5次标定取平均值。单次标定受噪声影响较大我的记录显示多次平均能使误差降低40%以上。温度影响激光雷达在低温环境下测距会有偏差建议在设备工作温度稳定后再进行标定。有次冬天在室外标定结果明显不如室内稳定。对于需要更高精度的场景可以考虑使用专业的标定靶球或多平面标定板。但就大多数应用而言这套基于ArUco的方法已经能提供足够好的结果而且成本几乎为零。