激光雷达障碍物检测实战 - 第2节
点云数据格式解析:PCD、BIN、LAS 文件格式详解
做激光雷达感知,第一关就是跟数据格式打交道。我记得刚入行那会儿,拿到一份点云数据,打开一看全是乱码,折腾了半天才发现是字节序搞反了。今天我就把几种常见的点云格式掰开揉碎了讲清楚。
1. PCD 格式——点云库的亲儿子
PCD 是 Point Cloud Library 的标准格式。说白了,它就是为点云处理量身定做的。我个人的习惯是,只要用 PCL 库,数据就存成 PCD,省心。
PCD 文件分两部分:头部和数据体。头部是纯文本,告诉你点云有多少点、每个点有哪些字段。数据体可以是 ASCII 或二进制。
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z intensity
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 123456
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 123456
DATA ascii
你看这个头部,FIELDS 定义了每个点的属性。我遇到过最坑的事:有人把 intensity 写成了 intensitiy,结果 PCL 直接报错。嗯,拼写错误要小心。
F 是浮点,I 是整型,U 是无符号整型。选错了类型,数据就全乱了。
2. BIN 格式——裸奔的二进制
BIN 格式没有头部,没有元数据,就是纯二进制数据。你想想看,一个文件里全是 01 串,不告诉你每个字节代表什么。这就像给你一把钥匙,但不告诉你哪把锁能开。
为什么还有人用?因为快。自动驾驶场景下,每秒要处理几十万点,BIN 格式读写速度最快。我曾在项目中用 BIN 格式做实时数据流,延迟比 PCD 低了将近 30%。
解析 BIN 文件时,你必须提前知道数据结构。比如 Velodyne 的 BIN 文件,每个点占 16 字节:
struct VelodynePoint {
float x; // 4 bytes
float y; // 4 bytes
float z; // 4 bytes
float intensity; // 4 bytes
};
3. LAS 格式——测绘界的标准
LAS 是 ASPRS 制定的标准格式,主要用于测绘和地理信息系统。它比 PCD 复杂得多,除了点坐标和强度,还能存分类信息(比如地面、建筑、植被)。
LAS 文件结构分三块:公共头、变长记录、点数据。公共头固定 227 字节,告诉你点数量、坐标范围、格式类型。变长记录可以存投影信息、元数据。点数据就是每个点的具体值。
| 字段 | 偏移量 | 大小 | 说明 |
|---|---|---|---|
| 文件签名 | 0 | 4 bytes | "LASF" |
| 文件源 ID | 4 | 2 bytes | 项目编号 |
| 全局编码 | 6 | 2 bytes | GPS 时间类型等 |
| 点数 | 107 | 4 bytes | 总点数 |
说实话,LAS 格式在自动驾驶里用得不多,主要是测绘那边在用。但如果你做高精地图,就绕不开它。
点云数据结构:XYZI 与 XYZRGB
点云数据说到底就是一堆点,每个点带几个属性。最常见的两种结构是 XYZI 和 XYZRGB。
XYZI——最常用的结构
XYZI 就是坐标加强度。强度值反映了激光回波的信号强度,对目标识别很有用。比如,路面的强度通常比植被低,金属护栏的强度特别高。
我习惯把 XYZI 存成 pcl::PointXYZI 类型。在代码里是这样:
#include <pcl/point_types.h>
pcl::PointXYZI point;
point.x = 1.23;
point.y = 4.56;
point.z = 7.89;
point.intensity = 128; // 0-255 范围
XYZRGB——带颜色的点云
XYZRGB 就是坐标加颜色。颜色信息通常来自相机图像,通过标定把像素颜色映射到点云上。这样点云就有了视觉信息,做语义分割时特别好用。
颜色在 PCL 里用 uint32_t 存储,RGB 各占 8 位。我见过新手直接赋值 255,结果颜色全乱了。正确的做法是用 pcl::RGB 结构体:
pcl::PointXYZRGB point;
point.x = 1.23;
point.y = 4.56;
point.z = 7.89;
// 正确设置颜色
uint8_t r = 255, g = 128, b = 64;
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
point.rgb = *reinterpret_cast<float*>(&rgb);
你想想看,为什么要把 RGB 塞进一个 float 里?因为 PCL 的 PointXYZRGB 结构体里,rgb 字段就是 float 类型。这是一种取巧的做法,用浮点数来存整型数据。
点云可视化工具:CloudCompare 与 rviz
光有数据不行,你得能看见它。我调试算法时,90% 的时间都在看可视化结果。这里介绍两个我常用的工具。
CloudCompare——点云分析利器
CloudCompare 是开源的点云处理软件,功能非常强大。它支持 PCD、LAS、PLY 等多种格式,还能做点云配准、分割、测量。
我个人最喜欢它的两个功能:
- 颜色编码:按高度、强度、分类等字段给点云上色,一眼就能看出数据分布
- 剖面工具:切一刀看截面,检查点云质量特别方便
我记得有一次,算法检测出的障碍物位置总偏。用 CloudCompare 打开原始点云,切了个剖面,才发现是标定参数错了,激光雷达装歪了 0.5 度。嗯,这种问题光看代码是看不出来的。
rviz——ROS 生态的标配
如果你用 ROS,rviz 就是标配。它专门用来可视化机器人数据,点云、图像、路径、TF 变换都能显示。
在 rviz 里显示点云很简单:
- 启动 rviz:
rosrun rviz rviz - 添加 PointCloud2 显示插件
- 选择话题名,比如
/velodyne_points - 设置颜色编码方式:XYZ、Intensity、RGB 都行
说实话,CloudCompare 和 rviz 各有千秋。CloudCompare 适合离线分析,功能全、精度高。rviz 适合在线调试,实时性好、与 ROS 无缝集成。我一般两个都用:白天用 rviz 调算法,晚上用 CloudCompare 做深度分析。
好了,关于点云数据格式和可视化,我就讲这么多。这些内容看着简单,但都是基本功。我见过太多人因为格式问题浪费大量时间。记住一句话:数据格式搞不清楚,后面的算法全是空中楼阁。