PCL(Point Cloud Library)是一个广泛使用的开源库,用于处理 3D 点云数据。它支持多种点云格式的读写,包括 PCD、PLY 和 OBJ 格式等。每种格式都有其特点和应用场景。下面是对 PCL点云库 支持的常见点云格式的详细介绍。
1. PCD (Point Cloud Data)
PCD(Point Cloud Data)是 PCL 自定义的专用格式,是 PCL 中最常用的点云文件格式。它设计上非常适合存储 3D 点云数据,支持多种数据类型,并可以根据需要扩展。
特点:
- 二进制与文本:PCD 文件可以是文本格式或二进制格式,文本格式适合人类阅读和编辑,二进制格式则更加紧凑和高效,适合存储大量数据。
- 灵活的结构:PCD 格式支持存储不同维度的点云数据,包括 X、Y、Z 坐标、颜色信息、法线、强度、表面法线等。
- 扩展性:PCL 可以通过添加额外的字段来支持新的数据类型或其他信息。
示例(文本格式):
# .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 3
HEIGHT 1
POINTS 3
DATA ascii
1.0 2.0 3.0 255
4.0 5.0 6.0 16711680
7.0 8.0 9.0 65280
这个示例表示一个包含 3 个点的点云,每个点有 X、Y、Z 坐标和 RGB 颜色信息。
应用场景:
- PCL 专用:PCD 格式主要用于 PCL 内部点云数据的存储和交换。
- 数据导出和交换:通过 PCD 格式,用户可以将点云数据从一个 PCL 应用程序导出,并在其他支持 PCD 格式的应用中使用。
2. PLY (Polygon File Format)
PLY(Polygon File Format)是一种常用于 3D 数据的文件格式,广泛应用于计算机图形学和计算机视觉领域。PCL 支持读取和写入 PLY 格式。PLY 文件通常用于存储 3D 网格、点云数据、三角形网格等信息。
特点:
- 文本与二进制:PLY 文件支持文本和二进制两种存储方式。文本格式适合查看和编辑,二进制格式更节省空间且适合处理大规模数据。
- 多种属性:除了点的坐标外,PLY 格式还支持存储颜色、法线、表面纹理坐标、面片信息等。
- 三维网格支持:PLY 格式常用于存储点云数据以及三维网格(例如三角面片数据)。
示例(文本格式):
ply
format ascii 1.0
element vertex 3
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 1
property list uchar int vertex_indices
end_header
1.0 2.0 3.0 255 0 0
4.0 5.0 6.0 0 255 0
7.0 8.0 9.0 0 0 255
3 0 1 2
这个示例表示一个点云,包含了三个点,每个点有 X、Y、Z 坐标以及 RGB 颜色信息,同时还存储了一个面片(三角形)。
应用场景:
- 三维模型交换:PLY 格式广泛应用于三维模型和网格数据交换,特别是面向科研和计算机图形学的领域。
- 扫描仪输出:很多 3D 扫描仪和计算机视觉系统使用 PLY 格式来存储点云数据。
3. OBJ (Wavefront Object)
OBJ 是一种常见的三维几何对象文件格式,广泛应用于 3D 模型和网格交换。虽然 OBJ 格式最初设计用于存储三维模型,但它也可以存储点云数据,尤其是在包含大量顶点和面片的数据时。
特点:
- 文本格式:OBJ 是纯文本格式,容易查看和编辑。
- 顶点与面片:OBJ 格式通常存储顶点、法线、纹理坐标和面片信息。尽管它主要用于网格数据,但也可以用于点云。
- 不支持颜色信息:标准的 OBJ 格式并不直接支持颜色信息,但是可以通过附加的 MTL 文件来指定材质和颜色属性。
示例(文本格式):
# OBJ file for point cloud data
v 1.0 2.0 3.0
v 4.0 5.0 6.0
v 7.0 8.0 9.0
该示例包含 3 个顶点,每个顶点表示一个点云的坐标。
应用场景:
- 三维模型交换:OBJ 格式广泛用于 3D 打印、计算机图形和游戏开发。
- 模型与点云结合:虽然 OBJ 文件更常用于存储网格数据,但也可以用作点云数据的交换格式,特别是在与网格数据结合的情况下。
4、PCL 支持的其他点云格式
除了 PCD、PLY 和 OBJ,PCL 还支持其他一些常见的点云数据格式:
- LAS (LiDAR Data Format):用于存储 LiDAR 数据,PCL 提供了对 LAS 格式的读取支持。
- XYZ:一种简单的点云格式,通常包含三个浮动数值:X、Y 和 Z 坐标。
- STL:主要用于三维模型交换,也可用于存储网格数据(由三角形面片组成的网格)。
5、总结
PCL 支持多种点云数据格式,常见的包括:
- PCD:PCL 专用格式,最适合存储点云数据,支持文本与二进制格式,灵活且高效。
- PLY:支持点云与网格数据的存储,广泛用于计算机图形学与三维模型交换。
- OBJ:常用于三维模型交换,尽管它主要用于网格数据,但也可以存储点云数据。
选择何种格式取决于应用需求,PCD 格式适用于 PCL 内部操作,PLY 和 OBJ 格式则适用于与其他 3D 应用程序交换数据时使用。
6、PCL点云库读取和保存PCD和PLY文件
在 PCL (Point Cloud Library) 中,读取 PCD 和 PLY 文件非常简单。PCL 提供了现成的读取接口,用于读取这两种格式的点云文件。下面是如何使用 PCL 读取 PCD 和 PLY 文件的详细示例。
1. 读取 PCD 文件
PCD 文件是 PCL 的标准点云数据格式,PCL 提供了 pcl::io::loadPCDFile
函数来读取 PCD 文件。
示例代码:
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <iostream>
int main(int argc, char** argv)
{
// 检查命令行参数
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <PCD file>" << std::endl;
return -1;
}
// 创建一个点云对象
pcl::PointCloud<pcl::PointXYZ> cloud;
// 加载 PCD 文件
if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], cloud) == -1)
{
PCL_ERROR("Couldn't read the PCD file\n");
return -1;
}
// 输出点云信息
std::cout << "Loaded PCD file with " << cloud.width * cloud.height
<< " data points." << std::endl;
// 输出点云的前几个点
for (size_t i = 0; i < cloud.points.size(); ++i)
{
std::cout << "Point " << i << ": ("
<< cloud.points[i].x << ", "
<< cloud.points[i].y << ", "
<< cloud.points[i].z << ")" << std::endl;
}
return 0;
}
代码解析:
pcl::PointCloud<pcl::PointXYZ> cloud;
:创建一个点云对象,pcl::PointXYZ
是表示每个点的结构体,包含 x、y、z 坐标。pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], cloud)
:加载 PCD 文件。该函数会将文件中的点云数据读取到cloud
对象中。如果读取失败,会返回 -1。cloud.points.size()
:点云包含的点数。- 输出每个点的坐标。
2. 读取 PLY 文件
PCL 同样提供了 pcl::io::loadPLYFile
函数来读取 PLY 文件。读取过程与 PCD 文件非常相似。
示例代码:
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <iostream>
int main(int argc, char** argv)
{
// 检查命令行参数
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <PLY file>" << std::endl;
return -1;
}
// 创建一个点云对象
pcl::PointCloud<pcl::PointXYZ> cloud;
// 加载 PLY 文件
if (pcl::io::loadPLYFile<pcl::PointXYZ>(argv[1], cloud) == -1)
{
PCL_ERROR("Couldn't read the PLY file\n");
return -1;
}
// 输出点云信息
std::cout << "Loaded PLY file with " << cloud.width * cloud.height
<< " data points." << std::endl;
// 输出点云的前几个点
for (size_t i = 0; i < cloud.points.size(); ++i)
{
std::cout << "Point " << i << ": ("
<< cloud.points[i].x << ", "
<< cloud.points[i].y << ", "
<< cloud.points[i].z << ")" << std::endl;
}
return 0;
}
代码解析:
pcl::PointCloud<pcl::PointXYZ> cloud;
:创建一个点云对象。pcl::io::loadPLYFile<pcl::PointXYZ>(argv[1], cloud)
:读取 PLY 文件并将数据存储到cloud
中。cloud.points.size()
:获取点云中的点数量。- 输出每个点的坐标。
3. 支持的点类型
在 PCL 中,点云数据结构 pcl::PointCloud<T>
是模板化的,可以包含不同的点类型,如:
pcl::PointXYZ
:表示每个点只有 3 个浮动值(x、y、z)。pcl::PointXYZRGB
:除了 x、y、z 外,还包含 RGB 颜色信息。pcl::PointNormal
:除了 x、y、z 坐标,还包含法线信息(normals)。
如果点云文件包含了颜色、法线等附加信息,你可以将模板参数从 pcl::PointXYZ
更改为如 pcl::PointXYZRGB
或 pcl::PointNormal
来读取这些额外的字段。
示例:读取带 RGB 信息的 PLY 文件
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <iostream>
int main(int argc, char** argv)
{
// 检查命令行参数
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <PLY file>" << std::endl;
return -1;
}
// 创建一个包含 RGB 信息的点云对象
pcl::PointCloud<pcl::PointXYZRGB> cloud;
// 加载 PLY 文件
if (pcl::io::loadPLYFile<pcl::PointXYZRGB>(argv[1], cloud) == -1)
{
PCL_ERROR("Couldn't read the PLY file\n");
return -1;
}
// 输出点云信息
std::cout << "Loaded PLY file with " << cloud.width * cloud.height
<< " data points." << std::endl;
// 输出点云的前几个点
for (size_t i = 0; i < cloud.points.size(); ++i)
{
std::cout << "Point " << i << ": ("
<< cloud.points[i].x << ", "
<< cloud.points[i].y << ", "
<< cloud.points[i].z << "), "
<< "RGB: (" << (int)cloud.points[i].r << ", "
<< (int)cloud.points[i].g << ", "
<< (int)cloud.points[i].b << ")" << std::endl;
}
return 0;
}
代码解析:
- 使用
pcl::PointXYZRGB
类型,这样可以读取点的 RGB 颜色信息。 - 每个点除了坐标 (x, y, z) 外,还包括颜色 (r, g, b)。
4. 总结
在 PCL 中,读取 PCD 和 PLY 文件非常简单。通过 pcl::io::loadPCDFile
和 pcl::io::loadPLYFile
函数,可以方便地将点云数据从文件加载到 pcl::PointCloud
对象中。你可以根据点云文件的格式和内容(如 RGB、法线等)选择合适的点类型(如 pcl::PointXYZ
、pcl::PointXYZRGB
等)。
- 对于 PCD 文件,使用
pcl::io::loadPCDFile
来读取。 - 对于 PLY 文件,使用
pcl::io::loadPLYFile
来读取。
至此完成第9讲的相关内容,欢迎喜欢的朋友订阅