第3章:点云数据基础:PCL库安装、点云数据结构、PCD/PLY文件格式解析与读写

点云数据,说白了就是三维空间里一堆点的集合。每个点带着XYZ坐标,有时候还带着颜色、法向量、强度这些附加信息。做3D视觉,点云就是我们的原材料。这一章,咱们就把点云的基础打牢。

3.1 PCL库的安装——别让环境配置卡住你

PCL(Point Cloud Library)是点云处理的事实标准。我入行那会儿,PCL还只有1.6版本,编译一次能折腾一整天。现在好多了,但该踩的坑一个不少。

Windows下的安装

我个人习惯用vcpkg来管理C++库,省心。

# 安装PCL核心库
vcpkg install pcl

# 如果需要可视化模块
vcpkg install pcl[visualization]

# 集成到CMake项目
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=[vcpkg-root]/scripts/buildsystems/vcpkg.cmake

如果你不想折腾编译,直接去PCL官网下载All-in-One Installer也行。嗯,这里要注意:安装路径不要带中文和空格,否则链接时会报一些莫名其妙的错误。

Linux下的安装

Ubuntu下最简单,一条命令搞定:

sudo apt-get install libpcl-dev pcl-tools

但有个坑——apt源里的PCL版本通常比较老。我曾经在Ubuntu 18.04上装1.8.1版本,结果有个新算法接口找不到,最后只能从源码编译。如果你需要最新特性,建议源码编译:

git clone https://github.com/PointCloudLibrary/pcl.git
cd pcl && mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
sudo make install
⚠️ 避坑指南: 我曾经在编译PCL时忘记安装VTK依赖,结果可视化模块死活编译不过。建议先执行 sudo apt-get install libvtk7-dev 再编译PCL。

3.2 点云数据结构——理解PCL的核心

PCL里最基础的数据结构是 pcl::PointCloud<T>。T是点类型,决定了每个点携带什么信息。

常用点类型

点类型 包含字段 典型应用场景
pcl::PointXYZ x, y, z 纯几何位置,最常用
pcl::PointXYZRGB x, y, z, r, g, b 带颜色的点云,RGB-D相机输出
pcl::PointXYZRGBA x, y, z, r, g, b, a 带透明通道的颜色点云
pcl::PointNormal x, y, z, normal_x, normal_y, normal_z 带法向量的点云,用于曲面重建
pcl::PointXYZRGBANormal 以上所有字段 全功能点,内存占用大

你想想看,一个点云文件动辄几百万个点,选对点类型能省不少内存。我在做仓储机器人项目时,一开始用了PointXYZRGB,后来发现颜色信息根本用不上,改成PointXYZ后内存占用直接降了三分之一。

点云的内存布局

PCL的点云数据是连续存储的,这一点很重要。底层其实就是一个vector,每个元素是一个点结构体。所以访问第i个点就是O(1)的复杂度。

pcl::PointCloud<pcl::PointXYZ> cloud;
cloud.width = 640;   // 如果是有序点云,width是每行点数
cloud.height = 480;  // height是行数,有序点云height > 1
cloud.is_dense = false; // 是否包含无效点(NaN)

// 访问点
float x = cloud.points[100].x;
float y = cloud.points[100].y;
float z = cloud.points[100].z;

// 遍历所有点
for (const auto& point : cloud.points) {
    // 处理每个点
}
💡 关键概念: 有序点云 vs 无序点云。有序点云类似一张图像,每个像素对应一个3D点,可以通过(u, v)坐标直接索引。无序点云就是一堆散点,只能遍历。RGB-D相机输出的通常是有序点云。

3.3 PCD文件格式解析——PCL的亲儿子

PCD(Point Cloud Data)是PCL的原生格式。说白了,就是PCL团队自己定义的,读写效率最高。

文件结构

一个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 4294967295
0.234 0.567 0.890 4278190335
...

头部字段说明:

  • VERSION:PCD版本,目前主流是0.7
  • FIELDS:每个点的字段名,空格分隔
  • SIZE:每个字段占用的字节数
  • TYPE:数据类型,F=float, I=int, U=unsigned int
  • COUNT:每个字段的元素个数,比如rgb是1个uint32
  • WIDTH/HEIGHT:点云尺寸,无序点云HEIGHT=1
  • VIEWPOINT:采集时的传感器位姿,用于坐标变换
  • POINTS:总点数
  • DATA:数据存储方式,ascii或binary
🎯 实战建议: 我建议生产环境用binary格式,文件小、读写快。调试阶段用ascii格式,方便用文本编辑器查看。PCL的 pcl::PCDReaderpcl::PCDWriter 会自动识别格式。

读写PCD文件

#include <pcl/io/pcd_io.h>

// 读取PCD文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("scene.pcd", *cloud) == -1) {
    PCL_ERROR("读取PCD文件失败\n");
    return -1;
}

// 写入PCD文件
pcl::io::savePCDFileASCII("output.pcd", *cloud);   // ASCII格式
pcl::io::savePCDFileBinary("output.pcd", *cloud);  // 二进制格式

3.4 PLY文件格式解析——通用性更强的选择

PLY(Polygon File Format)是斯坦福大学开发的格式,比PCD更通用。很多3D扫描仪和建模软件都支持PLY。说白了,如果你要和别的软件交换数据,PLY是更好的选择。

文件结构

PLY文件分ASCII和二进制两种,头部结构类似:

ply
format ascii 1.0
comment Created by PCL
element vertex 307200
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 0
property list uchar int vertex_indices
end_header
0.123 0.456 0.789 255 0 0
0.234 0.567 0.890 0 255 0
...

PLY支持两种元素:vertex(顶点)和 face(面片)。如果你只存点云,face可以设为0。如果要存三角网格,就需要定义face元素。

读写PLY文件

#include <pcl/io/ply_io.h>

// 读取PLY文件
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
if (pcl::io::loadPLYFile<pcl::PointXYZRGB>("model.ply", *cloud) == -1) {
    PCL_ERROR("读取PLY文件失败\n");
    return -1;
}

// 写入PLY文件
pcl::io::savePLYFileASCII("output.ply", *cloud);
pcl::io::savePLYFileBinary("output.ply", *cloud);
⚠️ 注意: 我曾经遇到过一个坑——PLY文件里的颜色顺序是RGB,但有些软件存的是BGR。如果你发现点云颜色不对,检查一下颜色通道顺序。PCL默认按RGB处理。

3.5 格式对比与选型建议

特性 PCD PLY
读写速度 快(原生支持) 中等
文件大小 较小(binary) 中等
通用性 PCL专用 广泛支持
支持网格 不支持 支持
元数据 支持VIEWPOINT等 支持comment

我个人习惯:内部处理用PCD,对外输出用PLY。你想想看,PCL读写PCD是零拷贝的,性能最好。但如果你要把点云发给客户或者导入Blender、MeshLab,PLY更友好。

3.6 本章知识体系

下面这张图帮你理清本章的核心逻辑:

点云数据基础 - 知识体系 点云数据基础 PCL库安装 点云数据结构 PCD文件格式 PLY文件格式 Windows Linux PointCloud<T> 点类型 有序/无序 内存布局 头部解析 读写API vertex/face 格式转换

嗯,这一章的内容就这些。PCL安装、点云数据结构、PCD和PLY格式的读写,都是后面所有章节的基础。你把这些搞定了,后面做滤波、配准、分割就顺手多了。


公众号:蓝海资料掘金营,微信deep3321