1、点云数据基础:什么是点云、点云数据格式(.pcd/.las/.ply)、点云可视化基础(Open3D/PCL)
好,咱们直接进入正题。点云是什么?说白了,就是一堆三维空间里的点。每个点带着自己的坐标 (x, y, z),有时候还带着颜色、强度之类的附加信息。你想想看,激光雷达扫一圈,打出去几百万束激光,每束光碰到物体弹回来,我们就记录下一个点的位置。几百万个点凑在一起,就成了点云。
我个人习惯把点云理解成「三维世界的照片底片」。照片是二维的,点云是三维的。你拿着相机拍一张照片,得到的是像素矩阵;激光雷达扫一圈,得到的就是点云矩阵。只不过这个矩阵里的每个元素,不是 RGB 值,而是空间坐标。
核心概念:点云 = 三维坐标系下的离散点集合。每个点至少包含 (x, y, z) 三个维度。
1.1 点云数据格式:.pcd / .las / .ply
做点云处理,绕不开文件格式。我刚开始接触的时候,被各种后缀名搞得头晕。其实常用的就三种:.pcd、.las、.ply。咱们一个一个说。
.pcd 格式(Point Cloud Data)
这是 PCL 库的亲儿子格式。PCL 是啥?Point Cloud Library,点云库,后面会细讲。.pcd 格式最大的优点是简单、清晰、好解析。文件头部用纯文本写明了点云的基本信息,比如点数、维度、数据类型。头部之后就是纯数据。
我给大家看一个典型的 .pcd 文件头:
# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 640
HEIGHT 480
VIEWPOINT 0 0 0 1 0 0 0
POINTS 307200
DATA ascii
0.123 0.456 0.789 0.5
0.234 0.567 0.890 0.6
...
嗯,这里要注意:WIDTH 和 HEIGHT 不一定代表图像尺寸。对于无序点云,HEIGHT 固定为 1,WIDTH 等于点数。对于有序点云(比如从深度相机来的),WIDTH 和 HEIGHT 才对应行列数。我曾经在这个坑里栽过跟头,解析一个 .pcd 文件时死活读不对点数,后来才发现是没区分有序和无序。
我的建议:做原型验证时,优先用 .pcd 格式。它简单、跨平台、PCL 和 Open3D 都原生支持。别折腾其他格式,除非有特殊需求。
.las 格式(LASer)
.las 是测绘和遥感领域的标准格式。它比 .pcd 复杂得多,支持更多的附加信息:回波次数、回波强度、分类标签(地面、建筑、植被等)、GPS 时间戳等等。说白了,.las 是为「专业测绘」设计的,.pcd 是为「通用点云处理」设计的。
如果你做的是车载激光雷达、机器人导航这类项目,大概率用 .pcd 就够了。但如果你做的是无人机测绘、地形建模、林业调查,那 .las 是绕不开的。我记得有一次做城市三维重建项目,甲方给的数据全是 .las 格式,里面每个点都带了分类标签,省了我不少标注的功夫。
| 特性 | .pcd | .las | .ply |
|---|---|---|---|
| 主要用途 | 通用点云处理 | 测绘、遥感 | 三维模型、网格 |
| 支持颜色 | 是 | 是 | 是 |
| 支持强度 | 是 | 是 | 否 |
| 支持分类标签 | 否 | 是 | 否 |
| 文件大小 | 中等 | 较大 | 中等 |
| 解析复杂度 | 低 | 高 | 中 |
.ply 格式(Polygon File Format)
.ply 原本是为三维网格(Mesh)设计的,但也可以存储点云。它的特点是支持顶点 + 面片的结构。如果你做的是三维重建,从点云生成网格后,通常保存为 .ply 格式。
我个人觉得,纯点云处理用 .ply 有点「杀鸡用牛刀」的感觉。但如果你需要同时保存点云和三角面片,那 .ply 是首选。Open3D 对 .ply 的支持非常好,读写都很方便。
避坑指南:我曾经遇到过一个 .ply 文件,用 Open3D 读进来全是 NaN 值。查了半天才发现,那个文件是用二进制格式写的,但头部声明了 ASCII。嗯,格式声明和实际编码不一致,这种坑在网上下载的数据集里很常见。遇到这种问题,先用文本编辑器打开看看头部,确认一下格式。
1.2 点云可视化基础:Open3D 与 PCL
做点云处理,可视化是刚需。你总不能对着几百万个数字发呆吧?得看到点云长什么样,才能判断算法效果好不好。常用的可视化工具有两个:Open3D 和 PCL。
Open3D:现代、轻量、Python 友好
Open3D 是我现在的主力工具。为什么?因为它太方便了。几行 Python 代码就能把点云显示出来,而且交互体验很好——旋转、缩放、平移都很流畅。
来看一个最简单的例子:
import open3d as o3d
# 读取点云
pcd = o3d.io.read_point_cloud("example.pcd")
# 可视化
o3d.visualization.draw_geometries([pcd])
就这三行,点云就出来了。你想想看,如果用 C++ 的 PCL,得写多少行?至少得配置 CMake、包含头文件、创建窗口、绑定鼠标事件……Open3D 把这些都封装好了。
我个人习惯在 Jupyter Notebook 里用 Open3D 做快速验证。写一段算法,跑一下,看一眼结果,不满意就改。这种「写-跑-看」的循环,Open3D 支持得非常好。
小技巧:Open3D 的 draw_geometries 函数支持传入多个几何体。你可以把原始点云和分割后的点云一起显示,用不同颜色区分。这样对比效果一目了然。
PCL:工业级、功能全面、C++ 生态
PCL 是点云处理的老牌库,功能极其全面。从滤波、分割、配准到识别,几乎你能想到的点云算法,PCL 都有实现。但它的学习曲线比较陡,而且配置环境是个体力活。
用 PCL 可视化点云,大概是这样:
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("example.pcd", *cloud);
pcl::visualization::PCLVisualizer viewer("Point Cloud Viewer");
viewer.addPointCloud(cloud, "cloud");
while (!viewer.wasStopped()) {
viewer.spinOnce();
}
return 0;
}
嗯,代码量明显多了。但 PCL 的优势在于深度和广度。比如你要做点云配准,PCL 提供了 ICP、NDT 等多种算法,而且参数可调范围很大。Open3D 虽然也有这些算法,但参数没那么多,灵活性稍差。
我记得有一次做工业检测项目,客户要求点云处理速度必须达到 30Hz。Open3D 的 Python 接口跑不满,后来用 PCL 的 C++ 实现,优化了一下参数,稳稳地跑到了 35Hz。所以我的建议是:快速原型用 Open3D,产品落地用 PCL。
怎么选?
其实不用纠结。我个人的工作流是这样的:
- 学习阶段:用 Open3D + Python。上手快,反馈及时,适合理解算法原理。
- 项目阶段:先用 Open3D 验证算法可行性,再用 PCL 做性能优化和工程化。
- 特殊需求:如果要做三维重建、网格处理,Open3D 更合适;如果要做点云配准、特征提取,PCL 更强大。
一句话总结:点云就是三维世界的「像素」,.pcd 适合通用处理,.las 适合测绘,.ply 适合网格。可视化工具,Open3D 图方便,PCL 图深度。两个都学,不吃亏。
好,这一章就到这里。下一章咱们聊聊点云的预处理——滤波和降采样。这可是点云处理的「洗菜」环节,菜洗不干净,后面炒菜再厉害也白搭。