- PCL官网:Point Cloud Library | The Point Cloud Library (PCL)
- PCL官方教程:Introduction — Point Cloud Library 0.0 documentation
- Fetching Title#ald1
一、PCL的结构和模块
1.1 整体结构
- PCL的整体结构图:
1.2 PCL模块
- PCL可实现点云相关的获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等功能:
- PCL模块化代码库功能
- libpcl filters :如采样、去除离群点、特征提取、拟合估计等数据实现过滤器
- libpcl features :实现多种 维特征,如曲面法线、曲率、边界点估计、矩不变量、主曲率,PFH FPFH 特征,旋转图像、积分图像, NARF 描述子, RIFT ,相对标准偏差,数据强度的筛选等。
- libpcl I/O :实现数据的输入和输出操作 ,例如点云数据文件(PCD) 的读写。
- libpcl segmentation :实现聚类提取,如通过采样 致性方法对一系列参数模型 如平面、柱面、球面、 线等进行模型拟合点云分割提取,提取多边形棱镜内部点云等。
- libpcl surface 实现表面重建技术,如网格重建、凸包重建 、移动最小乘法平滑等.
- libpcl register :实现点云配准方法,如 ICP
- libpcl keypoints :实现不同的关键点的提取方法,这可以用来作为预处理步骤,决定在哪儿提取特征描述符。
- libpcl range :实现支持不同点云数据集生成的范围图像。
1.3 PCL的PointT类型
参考博客:PCL中PointT类型详解_负壹的博客-CSDN博客
- PointXYZ------成员变量:float x,y,z;这是最常用的一个,只包含三维坐标X、Y、Z值,附加一个浮点进行对齐。可以通过points[i].data[0]或point[i].x访问X值。(即内部data数组和struct结构体数据共通)
union{
float data[4];
struct{
float x;
float y;
float z;
};
};
- Normal------float data_n[3], normal[3],curvature;另一个常用的数据类型,Normal结构体表示给定点所在样本曲面上的法线方向,以及对应曲率的测量值。例如访问法向量的第一个坐标可以通过points[i].data_n[0]或者points[i].noraml[0]或points[i ]. normal_x ,在此再次强调,曲率不能被存储在同一个结构体中,因为它会被普通的数据操作覆盖掉
union{
float data_n[4];
float normal[3];
struct{
float normal_x;
float normal_y;
float normal_z;
}
};
union{
struct{
float curvature;
}
float data_c[4];
};
其它多种类型参考博客介绍,用到时再查即可。
二、PCL I/0 模块及类介绍
参考博客:PCL库中I/O操作 PCD点云格式及输入输出模块(I/O)介绍
PCL 中I/O库提供了点云文件输入输出相关的操作类,并封装了 OpenNI 兼容的设备源数据获取接口,可直接从众多感知设备获取点云图像等数据。PCL 中有自己设计的内部 PCD 文件格式。
2.1 PCD(点云数据)文件格式
PCD 文件头包含条目:
VERSION——指定 PCD 文件版本。
FIELDS ——指定一个点可 以有的每一个维度和字段的名字。
SIZE——用字节数指定每一个维度的大小。
TYPE——用一个字符指定每 个维度的类型 。现在被接受的类型有I有符号、U无符号、F浮点。
COUNT ——指定每 个维度包含的元素数目。
WIDTH ——用点的数量表示点云数据集的宽度。
HEIGHT——用点的数目表示点云数据集的高度。
VIEWPOINT ——指定数据集中点 的获取视点。
POINTS ——指定点云中点的总数。
DATA 指定存储点云数据的数据类型
PCD文件格式的优势:
- 存储和处理有序点云数据集的能力——这一点对于实时应用,例如增强现实、机器学习领域十分重要。
- 二进制mmap/munmap数据类型是把数据下载和存储到磁盘上最快的方法。
- 存储不同的数据类型(支持所有的基本类型:char, short, int, float, double)——使得点云数据在存储和处理过程中适应性强并且高效,其中无效的点通常存储为MAN类型。
- 特征描述子的n维直方图——对于3D识别和计算机视觉应用十分重要。
2.2 读入和写出PCD格式点云文件
1.从pcd格式文件中读入点云
#include <iostream>
#include <pcl/io/pcd_io.h> // IO模块
#include <pcl/point_types.h> // 点类型
int main ()
{
// [1]首先我们使用以下语句创建一个指向pcl::PointXYZ类型的共享指针cloud,此处pcl::PointXYZ类型指的是只有XYZ三个维度位置信息的点云类型。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// [2]从磁盘加载PointCloud数据(例如文件名为test_pcd.pcd的文件),未成功读取则返回-1
if (pcl::io::loadPCDFile<pcl::PointXYZ> ("test_pcd.pcd", *cloud) == -1) //* load the file
{
PCL_ERROR ("Couldn't read file test_pcd.pcd \n");
return (-1);
}
// [3]打印pcd文件中点云的数据量(宽度*高度);
std::cout << "Loaded "
<< cloud->width * cloud->height
<< " data points from test_pcd.pcd with the following fields: "
<< std::endl;
// [4]打印出文件中点的位置信息,以下方式常用,需熟练使用。
for (const auto& point: *cloud)
std::cout << " " << point.x
<< " " << point.y
<< " " << point.z << std::endl;
return (0);
}
2.向pcd格式文件中写入点云
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
int main ()
{
// 创建点云的基本参数,以下指令描述了我们将要创建的模板化的PointCloud结构。每个点的类型都设置为pcl::PointXYZ,点云宽度为5,高度为1。
pcl::PointCloud<pcl::PointXYZ> cloud;
cloud.width = 5;
cloud.height = 1;
cloud.is_dense = false;
cloud.resize (cloud.width * cloud.height);
// 用随机生成的点向点云模板结构中填入数据
for (auto& point: cloud)
{
point.x = 1024 * rand () / (RAND_MAX + 1.0f);
point.y = 1024 * rand () / (RAND_MAX + 1.0f);
point.z = 1024 * rand () / (RAND_MAX + 1.0f);
}
// 将点云以ASCII码形式保存成PCD格式文件
pcl::io::savePCDFileASCII ("test_pcd.pcd", cloud);
std::cerr << "Saved " << cloud.size () << " data points to test_pcd.pcd." << std::endl;
// 打印点云
for (const auto& point: cloud)
std::cerr << " " << point.x << " " << point.y << " " << point.z << std::endl;
return (0);
}