2025-10-12
数据处理
00

目录

第1步:准备工作和环境检查
第2步:编写 Python 提取脚本
第3步:可视化pcd点云

提取 Livox Mid-360 的自定义点云(Custom Point Cloud) 和提取标准的sensor_msgs/msg/PointCloud2 格式点云有所不同,关键在于其消息类型。

Livox Mid-360 的 livox_ros_driver2 驱动通常会发布两种格式的点云:

标准格式: 话题名通常是 /livox/lidar,消息类型为 sensor_msgs/msg/PointCloud2。这种格式兼容性好,可以直接用 PCL (Point Cloud Library) 等工具处理。 自定义格式: 话题名通常是 /livox/lidar_custom,消息类型为 livox_ros_driver2/msg/CustomMsg。这种格式保留了 Livox 激光雷达更多的原始信息,如时间戳、线号、标签等,但需要专门的解析。

第1步:准备工作和环境检查

安装依赖: 确保 ROS 2 环境已经安装好。此外,我们需要一个库来处理和保存点云数据

pip install open3d numpy

ROS 2 工作空间需要能够识别 livox_ros_driver2/msg/CustomMsg 这个消息类型。执行以下命令检查系统是否能找到该消息类型:

ros2 interface show livox_ros_driver2/msg/CustomMsg

第2步:编写 Python 提取脚本

执行以下脚本后播放bag 包便可以提取bag包中的点云

python
import rclpy from rclpy.node import Node import numpy as np import open3d as o3d import os # 导入Livox自定义消息类型 from livox_ros_driver2.msg import CustomMsg class LivoxBagExtractor(Node): """ 一个用于从ROS 2 Bag文件中提取Livox CustomMsg并保存为PCD文件的节点。 """ def __init__(self): super().__init__('livox_bag_extractor') # --- 参数配置 --- # 从bag文件中监听的Livox自定义点云话题 self.livox_topic = '/livox/lidar' # !! 重要:根据你的bag文件信息修改此话题名 !! # 保存PCD文件的输出目录 self.output_dir = 'livox_pcd_output' # ---------------- # 创建订阅者 self.subscription = self.create_subscription( CustomMsg, self.livox_topic, self.custom_msg_callback, 10 # QoS profile depth ) # 创建输出目录 if not os.path.exists(self.output_dir): os.makedirs(self.output_dir) self.frame_count = 0 self.get_logger().info(f"节点已启动,正在监听话题: '{self.livox_topic}'") self.get_logger().info(f"PCD文件将保存在目录: '{self.output_dir}'") def custom_msg_callback(self, msg: CustomMsg): """ 回调函数,处理接收到的每一条CustomMsg消息。 """ self.get_logger().info(f"接收到第 {self.frame_count + 1} 帧数据,包含 {len(msg.points)} 个点。") # 准备一个列表来存储所有点的坐标 points_list = [] # 遍历消息中的每一个点 # CustomMsg中的 'points' 是一个 CustomPoint 类型的数组 for point in msg.points: # 提取x, y, z坐标 x = point.x y = point.y z = point.z points_list.append([x, y, z]) # 你也可以提取其他信息,例如: # reflectivity = point.reflectivity # tag = point.tag # line = point.line if not points_list: self.get_logger().warn("接收到的帧不包含任何点,跳过保存。") return # 将点列表转换为NumPy数组 points_np = np.array(points_list, dtype=np.float64) # 使用Open3D创建点云对象 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points_np) # 构建文件名,使用帧计数器以保证唯一性 filename = os.path.join(self.output_dir, f"livox_frame_{self.frame_count:05d}.pcd") # 保存为PCD文件 o3d.io.write_point_cloud(filename, pcd) self.get_logger().info(f"成功保存文件: {filename}") self.frame_count += 1 def main(args=None): rclpy.init(args=args) livox_extractor = LivoxBagExtractor() try: rclpy.spin(livox_extractor) except KeyboardInterrupt: pass finally: # 销毁节点并关闭rclpy livox_extractor.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()

有时候可能会遇到open3d与numpy的版本不兼容,执行以下命令升级相关库即可:

pip install --upgrade open3d scipy

第3步:可视化pcd点云

为了确保提取的点云文件正常,用pcl_viewer进行可视化

首先安装相关工具

sudo apt install pcl_tools

然后执行可视化命令:

pcl_viewer xxx.pcd

本文作者:James

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!