1、点云基本知识
学习掌握一门技术,一些必要的基本知识是很有必要的,下面对学习PCL库中的一些基本知识进行简要的介绍。
1.1、什么是点云
点云是由一系列数据点组成的集合,这些点通常代表三维空间中物体表面的点。点云数据可以通过各种三维扫描技术获得,如激光扫描(VLP系列)、结构光扫描( Kinect系列)或立体视觉扫描(Realsense系列)等。每个点通常包含三个坐标值(X、Y、Z),有时还包含颜色和反射率等其他信息。点云广泛应用于计算机视觉、机器人导航、三维建模、工业检测和文化遗产保护等领域。点云数据如下图1所示。
图 1
1.2 、点云数据的获取方式
点云数据的获取方式主要有以下几种:
激光扫描:利用激光扫描仪对物体表面进行细致的扫描,以获取其精确的三维坐标信息。如徕卡、法如、Z+F和天宝等激光扫描产品等。
结构光扫描:通过向物体表面投射特定的光纹图案,借助相机捕捉图案变形后的图像,进而计算出物体表面的详细三维信息。如梅卡曼德等产品。
立体视觉:采用两个或多个相机从不同视角拍摄物体,通过图像匹配和计算处理,精确地得到物体表面的三维坐标。如Realsense系列。
摄影测量:通过高分辨率的摄影设备从不同角度拍摄物体或场景,然后利用摄影测量学原理进行三维重建,提取出点云数据。
激光雷达(LiDAR):在飞行器或车辆上搭载激光雷达系统,通过发射激光脉冲并接收其反射信号,精确测量地物的三维坐标。激光雷达如VLP系列、Ouster系列和Livox Avia等
手持式扫描仪:采用便携式扫描设备直接对物体进行扫描,快速获取点云数据。如先临EinScan Libre和FreeScan Trio等系列产品。
三维重建软件:通过二维图像或视频资料,运用三维重建软件技术生成点云数据。如MVS和SFM技术相关的开源软件visSFM、colmap和MVE等开源项目。
传感器融合方式:整合多种传感器数据,包括深度相机、IMU(惯性测量单元)和GPS等,进行数据融合处理,得到相应的点云数据,在SLAM技术中比较常见。
1.3、点云数据的分类
在三维数据采集领域,点云数据的分类扮演着至关重要的角色。首先根据点云数据的组织结构,我们可以将其分为有序点云和无序点云两大类。
有序点云:这类点云通常遵循特定的规则进行排列,类似于图像网格中的像素布局,每个点都对应一个确切的像素位置。这种排列方式允许我们通过行和列的坐标快速定位到任何一个特定的点。有序点云的优势在于,通过了解两个相邻点之间的关系,最近邻点操作得以变得更加高效,从而加速计算过程,并且减少在PCL中某些算法的计算负担。
无序点云:与有序点云不同,无序点云数据缺乏固定的排列顺序,点与点之间没有固定的拓扑关系,这使得快速访问特定点变得较为困难。无序点云是比较普遍的点云形式,有序点云也可以看作无序点云来进行处理。
为了更清晰的区域有序点云和无序点云,参考示意图图2(有序点云)和图3(无序点云)。
图 2 有序点云
图 3 无效点云
此外,点云数据的来源亦也是分类的重要依据,常见的来源包括激光雷达、结构光扫描以及立体视觉等技术手段。
在点云数据的密度和分辨率方面,高密度点云数据因其包含大量点信息,能够提供更为详尽和精确的三维结构,适用于高精度重建或测量任务。而低密度点云数据则因点数较少,适用于快速获取场景的总体形状或进行初步分析。
在点云数据的动态特性方面,静态点云数据通常用于描述静止物体,其数据不随时间变化。相比之下,动态点云数据则用于捕捉动态物体或场景的变化,例如人体动作或车辆运动等,这类数据随时间变化而变化。
根据点云数据是否包含颜色信息,还可将其分为彩色点云与灰度点云。彩色点云数据包含了每个点的颜色信息,能够提供更为丰富的视觉信息。而灰度点云数据则仅包含每个点的灰度值,通常用于简化数据处理或降低存储需求。
不同类型的点云数据在应用场景和处理方法上存在差异,选择合适的点云数据类型对于实现特定的三维重建、测量或分析任务至关重要。
因此,在进行点云数据处理和应用时,必须充分考虑数据的来源、密度、分辨率、动态特性以及颜色信息等因素。例如,在进行城市规划和建筑建模时,高密度彩色点云数据能够提供更为精确和丰富的三维信息,有助于提高模型的准确性和视觉效果。而在自动驾驶车辆的环境感知系统中,动态点云数据则显得尤为重要,它能够实时捕捉车辆周围环境的变化,为车辆提供及时的决策支持。
综上所述,点云数据的分类和选择对于三维重建、测量和分析任务的成功至关重要。未来,随着技术的不断进步,点云数据的采集和处理技术将更加高效和精确,为各行各业提供更为强大的支持,推动相关领域的发展和创新。
1.4、常有的点云数据格式
点云格式是用于存储和传输点云数据的方式,点云数据的存储格式多样,主要包括以下几种:
PCD(Point Cloud Data):由PCL库提供的点云格式,支持存储点云的多种属性信息,在三维重建和机器人数据领域比较常用。
PLY(Polygon File Format):亦称作Stanford Triangle Format(斯坦福三角格式),由斯坦福大学开发提供,是一种具备高度灵活性的文件格式,能够记录包括颜色、透明度、表面法线等在内的多种属性信息,在科学研究和学术界比较常用。
LAS/LAZ:专为激光雷达数据设计的格式,其中LAS为无损压缩格式,而LAZ为LAS的压缩版本,在地理信息系统和测绘常用。
OBJ:作为一种广泛采纳的标准3D模型格式,其支持顶点、纹理坐标、法线以及面信息的存储,在虚拟现实和游戏开发比较常用。
STL(Stereolithography):主要用于3D打印领域,其内容通常仅限于几何信息,不涉及颜色或其他属性信息。
XYZ:一种基础的文本格式,每一行代表一个点,包含三个浮点数,分别对应点的X、Y、Z坐标,读写和处理方便,但缺乏其他属性信息。
PTS:与XYZ格式相似,同样是文本格式,但可能包含额外的属性信息。
PCAP:专为点云数据设计的二进制格式,由Autodesk开发,用于存储点云数据及其属性信息。
2、PCL点云库中的基本数据类型
掌握PCL点云库中的基本数据类型至关重要,因为PCL库内所有算法都是构建在这些基础数据类型之上的,它们为点云数据处理提供了坚实的支持。
2.1、PCL库中点(PointT)类型
在开发使用PCL点云库的过程中,最频繁使用的点类型共有11种,如表1所示。其他点类型并未在此详尽展示,将在后续应用中进行讲解。这些点类型的具体信息包含在文件#include <pcl/point_types.h>中。
点类型 |
成员变量 |
描述 |
pcl::PointXYZ |
float x, y, z |
三维点(x,y,z),使用最频繁 |
pcl::PointXYZI |
float x,y,z,intensity |
三维点+点强度信息,常用于激光点云 |
pcl::PointXYZL |
float x, y, z, uin32_t label |
三维点+点标签信息,常用于点云分割分类 |
pcl::PointXYZRGBA |
float x,y,z,uint32_t rgba |
三维点+颜色(r,g,b)+Alpha通道(透明度),常用透明对象的场景 |
pcl::PointXYZRGB |
float x,y,z,rgb |
三维点+颜色,常用于深度图点云 |
pcl::PointXYZRGBL |
float x, y, z, rgb, std::uint32_t label |
三维点+颜色信息+点标签 |
pcl::Normal |
normal[3], curvature |
法向量(normal_x,normal_y,normal_z)+点曲率信息 |
pcl::PointNormal |
float x,y,z,normal[3] |
三维点+法向量 |
pcl::PointXYZRGBNormal |
float x,y,z,rgb,normal[3], curvature |
三维点+颜色+法向量+曲率 |
pcl::PointXYZINormal |
float x,y,z,intensity,normal[3], curvature |
三维点+点强度+颜色+法向量+曲率 |
pcl::PointXYZLNormal |
float x, y, z, label, normal[3], curvature |
三维点+点标签+颜色+法向量+曲率 |
表 1
2.2、PCL点云库中点云(PointCloud)类型
PCL点云库中的核心点云类型为 PointCloud<T>,它是一个使用 C++ 模板类实现的。接下来,将对 PointCloud<T> 中的关键成员变量和常用成员函数进行详细注释和解释,PointCloud<T>,在文件#include <pcl/point_cloud.h>中。
1、主要成员变量
std::vector<PointT, Eigen::aligned_allocator<PointT> > points;
注释:存储PointCloud中所有 PointT 点类型的std::vector容器。
std::uint32_t width = 0;
注释:对于有序点云数据,width为点的列数;对于无有序点云数据,width为点的总数。
std::uint32_t height = 0;
注释:对于有序点云数据,height为点的行数,对于无有序点云数据,height为1。
bool is_dense = true;
注释: is_dense = true 时,表示点云是稠密的,点云中的每个点都是有效的信息,is_dense = false 时,表示点云是非稠密的,点云中有在一些缺失或无效的点,通常无序点云设置为false。
Eigen::Vector4f sensor_origin_;
Eigen::Quaternionf sensor_orientation_;
注释:采集当前点云数据传感器的位置-平移,采集当前点云数据传感器的姿态-旋转,常用的的比较少。
using Ptr = shared_ptr<PointCloud<PointT> >;
using ConstPtr = shared_ptr<const PointCloud<PointT> >;
注释:PointCloud<T>点云类的智能指针对象,使用频繁。
2、主要成员函数
常用的成员函数如下表2
bool empty () |
PointCloud中的points是否为空 |
void reserve (std::size_t n) |
分配 points的容量为n |
PointT* data() |
返回PointCloud中的points数据集为PointT指针 |
void resize(std::size_t count) |
重置 points的大小 |
PointT& at(std::size_t n) |
获取points中指定索引的点 |
PointT& front () |
获取points中第一点 |
PointT& back () |
获取points中最后一点 |
void assign(index_t count, const PointT& value) |
将 count个PointT类型的Value中拷贝到 points中 |
void push_back (const PointT& pt) |
往points中保存数据 |
reference emplace_back (Args&& ...args) |
往points中保存数据,速度push_back快 |
iterator insert (iterator position, const PointT& pt) |
往 points中插入点,在指定的迭代器位置 |
iterator erase (iterator position) |
删除 points中,指定迭代器位置的点 |
void swap (PointCloud<PointT> &rhs) |
交换两个PointCloud对象中的所有数据 |
void clear () |
清除PointCloud中 points的数据 |
Ptr makeShared () |
返回PointCloud对象的智能指针类型 |
PointT& at (int column, int row) |
对于有序点云获取points中指定行列位置的点 |
表2
3、应用示例
对PCL点云库中的点类型(PointT)和点云类型(PointCloud<T>)进行示例,在VS2019中新建文件PointCloudmian.cpp,内容如下:
/*****************************************************************//**
* \file PointCloudmian.cpp
* \brief
*
* \author YZS
* \date December 2024
*********************************************************************/
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
using namespace std;
int main(int argc,char *argv)
{
//点类型的使用
pcl::PointXYZ ptxzy;//点(x,y,z)
//访问点成员变量
ptxzy.x;
ptxzy.z;
ptxzy.z;
pcl::PointXYZI ptxyzl;//点+标签
pcl::PointXYZRGB ptxyzrgb;//点+RGB颜色
pcl::PointNormal ptxyzNormal; //点+法向量
//访问法向量信息
ptxyzNormal.normal_x;
ptxyzNormal.normal_y;
ptxyzNormal.normal_z;
pcl::Normal normal; //法向量
//........
//点云的使用
// 创建点云对象
pcl::PointCloud<pcl::PointXYZ> cloud;
//创建智能指针点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPtr(new pcl::PointCloud<pcl::PointXYZ>());
//有序点云
cloudPtr->width = 640;
cloudPtr->height = 480;
//稠密点云
cloudPtr->is_dense = true;//
//设置点云数据大小
cloudPtr->resize(cloudPtr->width * cloudPtr->height);
//无序点云
cloud.width = 307200;
cloud.height = 1;
//非稠密点云
cloud.is_dense = false;
for (int i;i<100;++i)
{
pcl::PointXYZ pt;
//pt.x = value ;
//pt.y = value;
//pt.z = value;
//往点云中插入点
cloudPtr->points.emplace_back(pt);
}
std::cout << "Hello PCL!" << std::endl;
system("pause");
return 0;
}
至此完成第二节PCL库中点云基本知识和数据类型结构,下一节我们将进入《PCL点云库中常用点云数据格式PCD和PLY以及其输入输出》的学习。