第2章:点云数据基础
大家好,我是你们的老朋友。今天咱们聊聊点云数据的基础。
说实话,我刚入行那会儿,拿到第一包激光雷达数据时,整个人是懵的。一堆三维坐标点,密密麻麻,完全不知道从哪下手。后来才明白,搞懂点云的数据结构,就像学开车先要认识方向盘和油门一样重要。
2.1 点云数据结构:XYZI 与 XYZRGB
点云说白了,就是一堆三维点的集合。每个点都带着自己的“身份证”——也就是属性信息。
2.1.1 XYZI 格式
这是最常见的格式。X、Y、Z 是空间坐标,I 是反射强度(Intensity)。
为什么强度这么重要? 我举个例子。你在路上扫描一个白色车牌和黑色轮胎,激光打回去的能量完全不同。强度值就能帮你区分它们。我在做车道线检测时,就靠强度值把白色车道线从灰色路面里揪出来,效果出奇的好。
核心要点: XYZI 是机械式激光雷达的标配。Velodyne、Hesai 的 16线、32线、64线雷达,输出的基本都是这个格式。
2.1.2 XYZRGB 格式
这个格式多了 RGB 颜色信息。每个点除了坐标,还带着红绿蓝三个通道的颜色值。
你可能会问:“激光雷达不是只发激光吗?哪来的颜色?” 嗯,这其实是融合的结果。通常是把摄像头图像和激光点云做对齐,把像素颜色赋给对应的点。我在做行人检测时,光靠点云形状有时分不清人和路灯杆,加上颜色信息后,准确率直接提升了十几个点。
我的小技巧: 如果你手头只有 XYZI 数据,又想用颜色信息,可以试试把强度值映射成灰度图。虽然不是真彩色,但聊胜于无。
2.2 常见激光雷达数据特点
市面上的激光雷达五花八门,但主要分两大类:机械式和固态。它们的点云数据特点完全不同。
2.2.1 机械式激光雷达
这种雷达有个旋转的“脑袋”,里面是一排激光发射器。Velodyne HDL-64E 就是典型代表。
- 数据特点: 360度水平视场角,垂直视场角一般30度左右。点云呈环状分布,一圈一圈的。
- 密度分布: 近处点密,远处点稀。因为激光束是放射状的。
- 常见问题: 有盲区。雷达正上方和正下方是扫不到的。我记得有一次做停车场项目,车顶装了64线雷达,结果车正上方的限高杆死活扫不全,后来不得不调整安装角度。
注意: 机械式雷达的旋转部件容易磨损。我见过一台用了两年的雷达,点云开始出现“丢帧”现象,就是某些角度突然没数据了。定期校准很重要。
2.2.2 固态激光雷达
固态雷达没有旋转部件,靠电子扫描或者闪光方式成像。比如 Livox 的 Horizon 系列。
- 数据特点: 视场角有限,一般水平120度左右。点云呈花瓣状或网格状分布,不像机械式那样规整。
- 密度分布: 相对均匀,没有明显的近密远疏现象。
- 优势: 体积小、寿命长、成本低。我最近做的一个园区无人车项目,就全用的固态雷达,装在车头两侧,效果很稳。
两种雷达怎么选? 我个人习惯是:需要360度感知的场景,比如 L4 级自动驾驶,必须上机械式。如果只是前向感知,比如 AEB(自动紧急制动),固态雷达完全够用,还省钱。
2.3 PCL 与 Open3D 库简介
工欲善其事,必先利其器。点云处理离不开好用的库。我主要用两个:PCL 和 Open3D。
2.3.1 PCL(Point Cloud Library)
PCL 是点云处理的老牌库,C++ 写的,功能极其强大。滤波、分割、配准、识别,几乎你能想到的点云算法,它都有。
我的评价: PCL 就像瑞士军刀,什么都能干。但学习曲线陡,编译起来也麻烦。我第一次编译 PCL 时,折腾了整整一天,各种依赖报错。
一个简单的 PCL 读取点云示例:
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
if (pcl::io::loadPCDFile<pcl::PointXYZI>("scan.pcd", *cloud) == -1) {
PCL_ERROR("Couldn't read file.\n");
return -1;
}
std::cout << "Loaded " << cloud->points.size() << " points." << std::endl;
2.3.2 Open3D
Open3D 是后来崛起的库,支持 C++ 和 Python。它的设计理念是“易用”。
- 优势: Python 接口非常友好,几行代码就能可视化点云。
- 适合场景: 快速原型开发、数据探索、教学演示。
- 缺点: 算法丰富度不如 PCL,一些高级功能需要自己实现。
用 Open3D 读取并显示点云:
import open3d as o3d
pcd = o3d.io.read_point_cloud("scan.pcd")
print(f"Loaded {len(pcd.points)} points.")
o3d.visualization.draw_geometries([pcd])
我的建议: 做工程落地用 PCL,性能好、稳定。做算法验证和快速实验用 Open3D,开发效率高。我现在的流程是:先用 Open3D 在 Python 里调通算法,再移植到 PCL 的 C++ 代码里上线。
2.4 本章小结
这一章我们聊了:
- 点云的两种常见数据结构:XYZI 和 XYZRGB
- 机械式与固态激光雷达的数据特点对比
- PCL 和 Open3D 两个库的适用场景
嗯,基础打牢了,后面咱们才能玩转降噪和地面分割。下一章,我会带大家亲手写代码,看看点云到底长什么样。