ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Livox+海康相机实时彩色点云建图全流程实战解析

Livox+海康相机实时彩色点云建图全流程实战解析 做实时彩色点云建图这个项目之前我天真地以为“跑通两个驱动再拼一下就能出图”实际折腾下来踩的坑比想象中多得多。Livox雷达的点云特性、海康相机的曝光策略、时间戳同步、外参标定每一步都有细节少留意一个就可能导致颜色错位、点云飘移甚至整个系统崩溃。这篇文章把我从零搞定的完整流程整理出来包括ROS环境配置、驱动编译、标定、同步、建图串联还有我在实操中遇到的问题和排查方法希望对正在做传感器融合或者准备上车这套设备的朋友有实际帮助。先说下我的硬件选型激光雷达用的是Livox Mid-360相机是海康的MV-CA050-10GC500万像素GigE工业相机工控机是一台普通i7笔记本外加一个千兆交换机。整个项目的目标很简单把海康相机拍摄的RGB信息映射到Livox产生的三维点云上并用FAST-LIO这类建图算法实时输出带有真实颜色纹理的地图。这样生成的地图不仅好看在后续做语义分割、目标识别、视觉定位时也非常有用。1. 项目整体设计与硬件架构1.1 为什么是“Livox 海康”这套组合激光雷达选型这件事很多新手上来就纠结“多少线”“多少米”。说实话对于中近距离的建图、导航、感知融合需求Livox Mid-360这类非重复扫描固态雷达是性价比很高的选择。它的视场角是360度水平、-7度到52度垂直比传统多线机械雷达更适合安装在机器人顶部而且点云密度在短时间积分后相当可观。更重要的是Livox官方提供了一套完整的ROS驱动配合FAST-LIO、Point-LIO等开源SLAM方案都有现成的接口省去大量底层适配工作。相机选择海康的原因也很实际海康工业相机在国产设备里SDK成熟度很高MVS的Linux版本做得完整支持GigE Vision协议可以方便地在ROS里通过驱动节点取流。和Livox雷达一样海康相机也支持PTPIEEE 1588时间同步这对后面做激光和图像的精确时间对齐非常关键。很多人在做雷达相机融合时会选择“雷达普通USB摄像头”虽然便宜但USB摄像头的曝光时间和时间戳控制都比较弱最后出现的拖影和颜色错位问题够折腾几个星期的。成本上一套Livox Mid-360加海康500万工业相机加镜头大概在1.5万到2万之间。如果预算有限雷达可以选Livox Avia或Horizon相机可以降级到200万像素但流程基本不变。核心是理解整套链路传感器原始数据 → 时间同步 → 内外参标定 → 投影取色 → 累积成彩色地图。1.2 硬件连接与网络规划第一步先别急着写代码把物理连接和网络规划做好。Livox Mid-360默认使用UDP协议传输点云数据雷达的默认IP通常是192.168.1.50不同批次可能不同以雷达标签为准也可以在Livox Viewer里修改。海康工业相机的默认IP一般是192.168.1.100这类地址。我的做法是准备一台千兆交换机把雷达、相机、工控机三台设备都接在同一个局域网里然后给工控机的网卡设置一个静态IP比如192.168.1.10子网掩码255.255.255.0。这一步很多人会踩坑如果工控机有多个网卡或者系统自带的网络管理工具如Netplan没配置好可能会出现“雷达能收到数据但相机连不上”之类的奇怪问题。建议先把Livox Viewer和MVS客户端各自测试一遍确保两个传感器能单独出数据再往下走。注意Livox雷达默认发送目标端口是2351如果防火墙开着记得放行UDP端口。海康相机在MVS里也需要调整“采流设置”里的包大小一般建议设置成8192或1440否则容易出现图像丢包导致的画面撕裂。1.3 系统架构从传感器到彩色点云整个系统分四层分别是数据采集层、同步层、标定层和建图层数据采集层Livox雷达驱动发布/livox/lidarPointCloud2消息海康相机驱动发布/hik_camera/image_rawImage消息。同步层通过PTP硬件同步或message_filters软同步确保两路数据的时间戳对齐。标定层先做相机内参标定Kalibr或OpenCV再做雷达相机外参标定得到从激光雷达坐标系到相机坐标系的变换矩阵。建图层使用FAST-LIO或自己写的彩色点云拼接节点在SLAM位姿估计的基础上把每一帧彩色点云变换到世界坐标系累积成彩色地图。这一架构的好处是松耦合每一层都可以单独调试、替换。比如你不想用FAST-LIO换成LIO-SAM或者Point-LIO只需要改最后一个建图节点就行前两层的代码都不用大变。这也是我推荐“把步骤拆开做”的原因如果一上来就想把整个系统一次性跑通排错会非常痛苦。2. 软件环境准备与驱动部署2.1 ROS环境选择Noetic还是HumbleLivox雷达和海康相机的驱动在ROS1和ROS2下都有方案但考虑到外参标定工具链比如livox_camera_calib、Autoware的标定模块很多还是ROS1实现初学者建议先用ROS1。我使用的是Ubuntu 20.04 ROS Noetic这也是目前Livox生态兼容性最好的一套组合。如果你的系统已经装了Ubuntu 22.04 ROS2 Humble也可以跑但很多标定工具需要自己折腾移植不建议新手直接上。安装ROS本身不是这篇文章的重点“鱼香ROS一键安装”这个工具确实能省不少事执行一条命令就可以把ROS装好wget http://fishros.com/install -O fishros . fishros选择“一键安装ROS Noetic”即可。装完之后记得验证一下source /opt/ros/noetic/setup.bash roscore能正常启动roscore就说明ROS环境没问题。然后创建一个工作空间mkdir -p ~/color_mapping_ws/src cd ~/color_mapping_ws catkin_make source devel/setup.bash2.2 Livox雷达驱动编译与配置Livox官方的驱动分两个版本旧版livox_ros_driver和新版livox_ros_driver2。对于Mid-360建议直接用livox_ros_driver2它对Mid-360支持更完整而且代码结构更清晰。cd ~/color_mapping_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git编译之前需要修改livox_ros_driver2/launch/msg_MID360.launch里的配置param nameuser_config_path value$(find livox_ros_driver2)/config/MID360_config.json /在对应的config/MID360_config.json文件中修改主机IP让驱动知道给工控机哪个地址发数据{ lidar_config: [ { ip: 192.168.1.50, host_ip: 192.168.1.10, cmd_port: 56000, msg_port: 56100, enable: true } ] }然后编译cd ~/color_mapping_ws catkin_make source devel/setup.bash roslaunch livox_ros_driver2 msg_MID360.launch启动后另开一个终端用rostopic hz /livox/lidar检查点云话题频率正常情况下Mid-360是10Hz左右点云数量根据场景不同会有起伏。提示如果雷达一直连不上先在Livox Viewer里确认雷达IP和设备状态然后测试工控机和雷达之间的连通性。Mid-360用的是网口直接通信不经过路由器中转所以交换机和网线质量也会影响连接稳定性。2.3 海康相机驱动编译与ROS节点配置海康相机的驱动分两层底层是官方MVS SDK负责相机发现、参数配置、图像采集上层是ROS驱动节点把图像数据转换成ROS的sensor_msgs/Image消息发布出去。先下载MVS SDK的Linux版本解压后按照README安装。安装完成之后验证一下能否用mvs_sample自带的客户端看到图像。能出图再编译ROS驱动。GitHub上有不少海康相机的ROS驱动包比如hikrobot_camera支持海康机器人所有GigE和USB相机或者基于MvCameraControl写的自定义节点。我用的驱动包大概长这样cd ~/color_mapping_ws/src git clone https://github.com/luckylucky/hikrobot_camera.git cd ~/color_mapping_ws catkin_make驱动节点启动后一般会发布类似/hik_camera/image_raw的Image话题。为了让图像的频率和曝光稳定建议在驱动配置里固定参数分辨率设为1280x1024、帧率设为10fps和雷达频率接近、曝光模式设为手动曝光曝光时间根据环境光调整室内一般3到8毫秒室外常见0.5到2毫秒。rosrun hikrobot_camera hikrobot_camera_node rostopic hz /hik_camera/image_raw能稳定输出图像之后记得用rqt_image_view看一眼画面确保没有过曝或过暗这一步能避免后面彩色点云整体偏色。3. 相机内参与激光雷达外参标定3.1 相机内参标定用Kalibr还是OpenCV彩色点云的精准度一半取决于外参一半取决于内参。如果内参不准确投影出的颜色会有明显的系统性偏移。相机内参标定有两种常见选择OpenCV的calibrateCamera和Kalibr。Kalibr的优势在于标定板类型丰富标定结果还会直接给出相机畸变模型参数文件适合后面扩展双目或IMU融合的场景。我用的是Kalibr因为它对标定板角点检测的鲁棒性更好。Kalibr使用的棋盘格或Aprilgrid你需要事先准备好一张打印出来的标定板。我的经验是标定板一定要贴平整不能有褶皱打印精度要高最好是A3尺寸格子边长不小于30mm。然后录制一段连续运动的图像运动时要保证标定板在不同位置、不同角度都有出现画面边缘也要覆盖到因为畸变参数主要靠边缘信息约束。rosbag record -O camera_calib.bag /hik_camera/image_raw录制一分钟左右转为Kalibr格式然后运行kalibr_calibrate_cameras --target april_6x6_80x80cm.yaml \ --bag camera_calib.bag \ --topics /hik_camera/image_raw \ --models pinhole-equi --show-extraction标定完成后会生成camchain.yaml里面包含了相机内参矩阵、畸变系数和畸变模型。如果你手里的相机是针孔模型畸变模型一般选择radtan如果是鱼眼镜头就选equi千万别选错选错了后期标定外参会非常痛苦。3.2 激光雷达与相机外参标定外参标定是整个流程里最磨人、也是最核心的一步。外参变换矩阵的含义是“激光雷达坐标系下的三维点经过坐标变换后落在相机坐标系下的位置”。标定方法有很多我尝试过Autoware自带的calibration_camera_lidar也试过港科大的livox_camera_calib最终推荐后者原因是它对Livox点云和棋盘格标定板做了专门优化标定精度高过程也相对自动化。livox_camera_calib的原理大致是在点云中拟合标定板的平面提取出板面的四条边界线和角点同时在图像中检测棋盘格角点然后通过非线性优化求出旋转矩阵和平移向量。这个方案很适合Mid-360这种“点云分布不规则”的雷达它不需要你人为在点云里切出完整的棋盘格形状算法会自动处理。使用时需要准备以下条件一个硬质棋盘格标定板我建议A1尺寸如果找不到就用A2但一定要贴在硬纸板或KT板上不能弯曲。标定板距离雷达不要太远我一般放在1到3米范围内太远点云太疏太近视场角内可能拍不全。整个标定过程需要保持雷达和相机静止标定板通过旋转、平移变换不同的姿态至少采集10组数据。# 采集标定数据 rosbag record -O calib_data.bag /livox/lidar /hik_camera/image_raw # 启动标定程序 roslaunch livox_camera_calib calib.launch标定完成后会得到外参矩阵通常表现为一个4x4的齐次变换矩阵。保存好这个矩阵下一节的投影取色全靠它。注意我在标定时发现一个很常见的坑——标定板在图像中反光严重导致棋盘格角点检测失败。解决办法是使用哑光打印纸或者把标定板稍微调整角度避免镜面反射。另外标定板不能悬空晃动稍微抖一下点云拟合就会偏。4. 时间同步彩色点云不出错的关键4.1 硬件同步方案PTP如果雷达和相机的时间不同步哪怕只有几十毫秒的偏差叠加在移动的机器人上颜色就会错位得离谱。举例来说雷达在t0时刻扫描的点云和相机在t0100ms时刻拍摄的图像如果机器人以0.5m/s的速度前进就已经有5厘米的位置偏移反映在彩色点云上就是边缘颜色溢出。最理想的方式是硬件同步时间基准由PTPIEEE 1588提供。Livox Mid-360自带PTP从时钟功能海康工业相机也支持IEEE 1588。配置方法是在工控机上安装PTP客户端如linuxptp运行ptp4l把工控机变成PTP主时钟雷达和相机自动同步到主时钟上。这样两路信号的时间戳可以做到亚毫秒级对齐。sudo apt install linuxptp sudo ptp4l -i eth0 -m -S输出里的master offset值越小越好一般维持在微秒量级就说明同步生效了。需要注意PTP要求整个链路是千兆网线直连或通过千兆交换机百兆老交换机对PTP支持不好同步精度会明显下降。4.2 软同步方案message_filters如果你的硬件不支持PTP也可以退而求其次用软同步。ROS里最常用的工具是message_filters的ApproximateTimeSynchronizer它会寻找时间戳最接近的图像和点云进行匹配。typedef message_filters::sync_policies::ApproximateTimesensor_msgs::PointCloud2, sensor_msgs::Image SyncPolicy; message_filters::Subscribersensor_msgs::PointCloud2 lidar_sub(nh, /livox/lidar, 10); message_filters::Subscribersensor_msgs::Image image_sub(nh, /hik_camera/image_raw, 10); message_filters::SynchronizerSyncPolicy sync(SyncPolicy(10), lidar_sub, image_sub); sync.registerCallback(boost::bind(callback, _1, _2));采用软同步时建议把雷达频率和相机帧率都设置成10Hz这样匹配效果会好很多。但软同步的代价是偶尔会漏帧而且如果传感器频率差异过大回调可能长时间触发不了。因此如果你做的是移动速度比较快的系统比如无人车、无人机尽量上PTP硬同步如果是原地建图或者速度很慢的巡检机器人软同步可以应付。5. 实时彩色点云生成与融合5.1 点云投影取色的数学原理彩色点云的生成本质上是坐标系变换和相机投影。假设激光雷达坐标系下有一个三维点 (P_l (x_l, y_l, z_l))我们要把它变换到相机坐标系[ P_c R_{lc} \cdot P_l t_{lc} ]其中 (R_{lc}) 和 (t_{lc}) 就是上一节标定得到的外参。然后将相机坐标系下的点投影到像素平面[ u f_x \cdot \frac{x_c}{z_c} c_x, \quad v f_y \cdot \frac{y_c}{z_c} c_y ]其中 (f_x, f_y) 是相机内参中的焦距(c_x, c_y) 是主点坐标。最后把像素坐标 ((u,v)) 处的RGB值赋给这个三维点就完成了取色。需要注意一个细节每个三维点投影到图像后像素坐标如果落在图像边界之外或者该点的深度值 (z_c) 是负数说明点在相机后面都要直接丢弃否则会出现明显的彩色飞点。在ROS的PointCloud2消息里颜色的存储方式是把RGB三个通道打包成一个浮点数赋值时用pcl::PointXYZRGB结构体会方便很多。5.2 实时拼接彩色点云节点看原理不难写起来也不复杂。我自己写了一个color_fusion_node订阅三路数据雷达点云、相机图像、外参或者从静态tf加载然后对每一帧点云做投影取色发布成/color_cloud。核心部分如下void cloudCallback(const sensor_msgs::PointCloud2::ConstPtr cloud_msg, const sensor_msgs::Image::ConstPtr image_msg) { cv::Mat image cv_bridge::toCvCopy(image_msg, bgr8)-image; pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloudpcl::PointXYZ()); pcl::fromROSMsg(*cloud_msg, *cloud); pcl::PointCloudpcl::PointXYZRGB::Ptr color_cloud(new pcl::PointCloudpcl::PointXYZRGB()); for (auto point : cloud-points) { Eigen::Vector3d p_lidar(point.x, point.y, point.z); Eigen::Vector3d p_cam R_lc * p_lidar t_lc; if (p_cam(2) 0) continue; double u fx * p_cam(0) / p_cam(2) cx; double v fy * p_cam(1) / p_cam(2) cy; if (u 0 || u image.cols || v 0 || v image.rows) continue; pcl::PointXYZRGB pt; pt.x point.x; pt.y point.y; pt.z point.z; pt.b image.atcv::Vec3b(v, u)[0]; pt.g image.atcv::Vec3b(v, u)[1]; pt.r image.atcv::Vec3b(v, u)[2]; color_cloud-points.push_back(pt); } // 发布 /color_cloud }这个节点本身不涉及SLAM只是实时输出“当前视觉范围内的彩色点云”。如果机器人静止你可以在Rviz里直观地看到三维空间中物体的颜色如果机器人动了你会发现点云是重叠的因为还没有累积到世界坐标系里。单帧彩色点云看起来没问题之后就可以进入建图阶段了。6. 实时彩色点云建图实操流程6.1 建图方案选型与FAST-LIO部署提到Livox雷达的实时建图大家首先想到的就是FAST-LIO和它的改进版FAST-LIO2以及港科大的Point-LIO。这些算法都在Livox点云上做过很好的适配Mid-360可以直接跑。FAST-LIO2的核心思想是“迭代误差状态卡尔曼滤波器”它把IMU和激光雷达点云紧耦合在一起即使在快速旋转或移动的场景下也能保持较高的定位建图精度。我的建图配置很简单Mid-360本身不带IMU但雷达内有一个IMU数据可以通过驱动发布话题名通常是/livox/imu。如果你外接另外的IMU也可以配置到FAST-LIO里但初次调试建议直接用雷达内置IMU省事。cd ~/color_mapping_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd FAST_LIO git submodule update --init cd ~/color_mapping_ws catkin_makeFAST-LIO的launch文件需要根据雷达型号修改配置最常见的是改config/下的yaml文件把点云话题名设为/livox/lidarIMU话题设为/livox/imu并且关掉外接IMU相关参数。6.2 完整的启动流程与launch整合我最推荐的方式是把整套流程做成一个launch文件依次启动驱动 → 相机 → 彩色融合节点 → FAST-LIO → TF发布。launch !-- Livox雷达 -- include file$(find livox_ros_driver2)/launch/msg_MID360.launch / !-- 海康相机 -- node namehik_camera_node pkghikrobot_camera typehikrobot_camera_node outputscreen / !-- 外参静态TF -- node pkgtf2_ros typestatic_transform_publisher namelidar_to_camera_broadcaster args0.123 -0.014 0.058 0.002 -0.015 0.009 base_link camera_link / !-- 彩色点云融合 -- node namecolor_fusion_node pkgcolor_map typecolor_fusion_node outputscreen / !-- FAST-LIO建图 -- include file$(find fast_lio)/launch/mapping_mid360.launch / /launch运行后在Rviz里添加两个显示一个是FAST-LIO发布的全局地图一般话题名是/Odometry或/cloud_registered另一个是彩色融合节点发布的/color_cloud。实际操作时我建议先把机器人固定好原地旋转一周让FAST-LIO初始化成功然后缓慢移动观察/color_cloud是否随着运动逐渐累积成一幅清晰的彩色地图。如果颜色和位置都正确说明驱动、同步、标定、建图全链路都通了。整个过程我一般会在室内灯光充足的走廊测试光线均匀、墙面纹理清晰非常适合验证彩色映射效果。7. 常见问题与排查技巧7.1 常见问题速查表把我在项目里或朋友测试时遇到的问题整理成一张速查表方便你对照排查现象可能原因解决办法雷达收不到数据IP配置错误、网线松动、防火墙拦截用Livox Viewer检查雷达状态确认工控机与雷达在同一网段开放UDP端口相机图像撕裂网络包被拆分不合理、交换机性能不足在MVS里调整“包大小”为8192使用千兆交换机避免Wi-Fi连接相机图像正常但点云颜色错位外参不准确或时间不同步重新做外参标定检查是否有PTP公告消息确认两路数据的时间戳差值点云颜色有大量黑点投影坐标超出图像边界或者点被遮挡增加深度判断条件排除z0以及像素坐标越界的点FAST-LIO建图飘IMU未正确初始化、点云畸变严重、雷达安装震动让雷达静止几秒后再移动检查IMU数据频率是否稳定加固雷达安装彩色点云整体偏色相机曝光设置不当白平衡未校正把海康相机白平衡设为自动或手动校准室外交为标准D65色温7.2 几个必须强调的细节时间戳对齐是最容易出问题的地方。我见过很多人外参标定得很准但最后出来的彩色点云还是错位排查半天发现是相机驱动发布的话题时间戳用的是本地系统时间而雷达用的是PTP时间两者有几百毫秒偏差。遇到这种情况可以直接用rostopic echo看两路消息头的时间戳把偏差算出来在相机驱动里加一个time_offset参数补偿。另外外参标定后一定不要动雷达和相机的物理位置哪怕只是松了一颗螺丝外参会全部失效。我在小车刚装好的头几天因为线材拉扯导致雷达支架移位重新标定了两次后来干脆用了带定位销的安装板才彻底避免这个问题。彩色点云拼接节点在长时间运行时内存增长也很值得关注。如果你用PCL累积全局地图点云数量会不断膨胀。建议在插入全局地图时加上体素滤波voxel grid比如设置0.05m的体素每隔一段时间做一次降采样既能控制内存又能让地图更干净。注意如果在移动过程中发现彩色点云的“颜色部分”延迟比几何部分大多半是图像曝光时间过长或者相机处理管线的延时过高。把曝光时间调小并且关闭相机自动曝光改用固定曝光延迟会低很多。最后再分享两个小技巧第一个是调参的顺序问题。很多新手喜欢一次性把所有参数调到完美但彩色点云这个系统里建议按“点云几何准确 → 颜色对齐 → 整体融合”的顺序来调。先把激光雷达的建图跑稳确认几何不飘再调整彩色融合否则几何都飘着你根本不知道颜色错位到底是外参的锅还是建图的锅。第二个是数据记录的思路。每次试验前我习惯先录一段原始rosbag包括雷达点云、相机图像和FAST-LIO的位姿轨迹。这样如果事后发现彩色地图有问题可以离线反复重放数据调参不用一遍遍推着机器人在外面跑。这个习惯帮我省了大量现场调试时间。这套Livox加海康的实时彩色点云建图流程完整跑通之后你会发现其实每个环节都不是特别难难的是把细节串联起来。希望这篇文章能帮你少走一些弯路后面做基于彩色点云的目标检测、语义地图、或者室内三维重建的时候这套系统都可以作为很好的数据基础。
返回列表