《点云库PCL学习教程》第6章-八叉树教学内容.ppt
点云库点云库PCLPCL学习教程学习教程第第6 6章章-八叉树八叉树建立空间索引在点云数据处理中已被广泛应用,常见空间索引一般是自顶向下逐级划分空间的各种空间索引结构,比较有代表性的包括BSP树、KD树、KDB树、R树、R+树、CELL树、四叉树和八叉树等索引结构,而在这些结构中KD树和八叉树在3D点云数据组织中应用较为广泛。PCL对八叉树的数据结构建立和索引方法进行了实现,以方便在此基础上的其他点云处理操作。本章首先对常用的点云空间索引方法octree概念进行介绍,然后对PCL的octree相关模块及类进行简单说明,最后通过应用实例来展示如何对PCL中octree模块进行灵活运用。本章各小节目录6.1 octree概述及相关算法简介6.2 PCL中octree模块及类介绍6.3 应用实例解析6.1 octree概述及相关算法简介八叉树结构是由Hunter博士于1978年首次提出的一种数据模型。八叉树结构通过对三维空间的几何实体进行体元剖分,每个体元具有相同的时间和空间复杂度,通过循环递归的划分方法对大小为2n2n2n的三维空间的几何对象进行剖分,从而构成一个具有根节点的方向图。在八叉树结构中如果被划分的体元具有相同的属性,则该体元构成一个叶节点;否则继续对该体元剖分成8个子立方体,依次递归剖分,对于2n2n2n大小的空间对象,最多剖分n次,如图6-1所示。6.2 PCL中octree模块及类介绍PCL中octree库提供了octree数据结构,利用FLANN进行快速邻域检索。邻域检索在匹配、特征描述子计算、领域特征提取中是非常基础的核心操作。octree模块利用十几个类实现了利用octree数据结构对点云的高效管理和检索,以及相应的一些空间处理算法,例如压缩、空间变化检测,其依赖于pcl_common模块。octree模模块中中类说明明目前PCL中octree模块中目前共有16个类,以后有可能增加。1.class pcl:octree:Octree2BufBase类Octree2BufBase实现了同时存储管理两个八叉树于内存中,如此,可以非常高效地实现八叉树的建立管理等操作,并且该类实现对临近树节点结构的变化探测,对应到空间点云,其就可以对空间曲面的动态变化进行探测,在进行空间动态变化探测中非常有用,例如目前基于kinect设备的体感交互应用。类Octree2BufBase关键成员函数:void setMaxVoxelIndex(unsigned int maxVoxelIndex_arg)设置在各个维度上最大的体素个数。void setTreeDepth(unsigned int depth_arg)设置八叉树的深度,需要在初始化八叉树时设置。void add(unsigned int idxX_arg,unsigned idxY_arg,unsigned int idxZ_arg,const DataT&data_arg)在idxX、idxY、idxZ对应的叶子节点上填充DataT的数据,其中idxX、idxY、idxZ为在三个维度上的整型索引值。bool existLeaf(unsigned int idxX_arg,unsigned int idxY_arg,unsigned int idxZ_arg)const判断在idxX、idxY、idxZ对应的叶子节点是否存在,如果存在返回true,否则返回false。unsigned int getLeafCount()const返回在该八叉树中的叶子数目。unsigned int getBranchCount()const返回在该八叉树中的分支数目。void deleteTree(bool freeMemory_arg=false)删除八叉树的结构及其叶子节点。void deletePreviousBuffer()删除另一个缓冲区中对应八叉树的结构及其叶子节点。void deleteCurrentBuffer()删除当前缓冲区中对应八叉树的结构和其叶子节点。void switchBuffers()交换缓冲区,并重设八叉树结构。void serializeTree(std:vector&binaryTreeOut_arg,bool doXOREncoding_arg=false)串行化输出八叉树结构到binaryTreeOut_arg向量,doXOREncoding_arg设置输出时是否将当前缓冲区与后台缓冲区中数据进行异或操作后再输出,异或操作是两个八叉树结构之间差异数据的输出。void serializeTree(std:vector&binaryTreeOut_arg,std:vector&dataVector_arg,bool doXOREncoding_arg=false)串行化重载函数,其中参数dataVector_arg存储八叉树中叶子节点上的数据,其他两个参数同上。void serializeLeafs(std:vector&dataVector_arg)参数dataVector_arg存储八叉树中叶子节点上的数据,该函数只串行化八叉树中的数据。void serializeNewLeafs(std:vector&dataVector_arg,const int minPointsPerLeaf_arg=0)串行化当前缓冲区八叉树中存在但在后台缓冲区八叉树中不存在的节点数据,其中,minPointsPerLeaf_arg为需要串行化的节点中点的最小个数,如果点个数小于该值则不串行化此新节点。void deserializeTree(std:vector&binaryTreeIn _arg,bool doXORDecoding_arg=false)反串行化,参数意义上同上面对应的串行化函数。2.class pcl:octree:OctreeBase类OctreeBase为八叉树基类,其关键成员函数参考其他类介绍。3.class pcl:octree:OctreeBaseWithState类OctreeBaseWithState为带有状态的八叉树基类,其中额外存储的状态多用于可见性估计,同样其关键成员函数参考其他类的介绍。4.class pcl:octree:OctreeIteratorBase类OctreeIteratorBase为八叉树迭代器的基类,用于深度优先或广度优先遍历八叉树时使用。类OctreeIteratorBase关键成员函数:void reset()初始化迭代器。const OctreeKey&getCurrentOctreeKey()const获取当前八叉树节点对应迭代器的键值。unsigned int getCurrentOctreeDepth()const获取当前八叉树迭代器对应节点所在的深度值。const OctreeNode*getCurrentOctreeNode()const获取当前八叉树节点。bool isBranchNode()const判断当前节点是否为分支节点,是返回true,否则返回false。bool isLeafNode()const判断当前节点是否为叶子节点,是返回true,否则返回false。char getNodeConfiguration()const获取当前节点的设置对应的比特位值。virtual void getData(const DataT*&data_arg)const获取当前节点包含数据的首个元素。virtual void getData(std:vector&dataVector_arg)const获取当前节点对应的向量数据。virtual unsigned long getNodeID()const获取当前节点对应的整数ID。5.Class pcl:octree:OctreeDepthFirstIterator6.class pcl:octree:OctreeDepthFirstIterator7.class pcl:octree:OctreeLeafNodeIterator以上3个类都继承于OctreeIteratorBase,分别实现深度优先遍历、广度优先遍历、叶子节点迭代器,关键函数参考其基类。8.class pcl:octree:OctreePointCloud类OctreePointCloud为针对点云实现的八叉树数据结构与相关算法,基于该类继承出多个子类,实现不同的点云处理或操作,如图6-2所示。类OctreePointCloud关键成员函数:void setInputCloud(const PointCloudConstPtr&cloud_arg,const IndicesConstPtr&indices_arg=IndicesConstPtr()设置八叉树管理的点云,其中cloud_arg为指向点云对象的指针,indices_arg为真正需要输入的点云的索引序列。void setEpsilon(double eps)设置近邻搜索时的误差限。void setResolution(double resolution_arg)设置为点云建立的八叉树结构的分辨率,即体素的大小。void addPointsFromInputCloud()显示调用将点云添加到八叉树管理结构中。void addPointFromCloud(const int pointIdx_arg,IndicesPtr indices_arg)添加对应索引中的点到八叉树中,其中pointIdx_arg为索引,indices_arg索引序列的指针。void addPointToCloud(const PointT&point_arg,PointCloudPtr cloud_arg,IndicesPtr indices_arg)添加点point_arg到点云cloud_arg的indices_arg索引下,同时添加到八叉树中。bool isVoxelOccupiedAtPoint(const PointT&point_arg)const判断点point_arg所处的空间是否存在八叉树体素中。bool isVoxelOccupiedAtPoint(const double pointX_arg,const double pointY_arg,const double pointZ_arg)const判断点(pointX_arg,pointY_arg,pointZ_arg)所处的空间是否存在八叉树体素中。int getOccupiedVoxelCenters(AlignedPointTVector&voxelCenterList_arg)const获取所有被点云占据的体素的中心并存储在voxelCenterList_arg中,返回值为被占据的体素的个数。int getApproxIntersectedVoxelCentersBySegment(const Eigen:Vector3f&origin,const Eigen:Vector3f&end,AlignedPointTVector&voxel_center_list,float precision=0.2)用参数origin和end给定空间一线段,该函数求得与该线段相交的体素中心,存储在voxel_center_list,并返回相交体素的个数。void deleteVoxelAtPoint(const PointT&point_arg)删除指定点所在的八叉树所管理的体素或叶子节点。void defineBoundingBox(const double minX_arg,const double minY_arg,const double minZ_arg,const double maxX_arg,const double maxY_arg,const double maxZ_arg)指定八叉树的包围盒,参数为三个维度的上下限,八叉树中一旦存储管理元素了,则包围盒大小就不能再改变。void getBoudingBox(double&minX_arg,double&minY_arg,double&minZ_arg,double&maxX_arg,double&maxY_arg,double&maxZ_arg)const获取包围盒3个维度的上下限。double getVoxelSquaredDiameter(unsigned int treeDepth_arg)const获取八叉树中指定深度对应体素的内切圆的直径。double getVoxelSquaredSideLen(unsigned int treeDepth_arg)const获取八叉树中指定深度对应体素的立方体的边长。9.class pcl:octree:OctreePointCloudChangeDetector类OctreePointCloudChangeDetector实现了创建一八叉树,该八叉树由新增加的叶子节点组成,该八叉树分辨率需要初始化,包围盒可自适应调整。类OctreePointCloudChangeDetector关键成员函数,未列出的参考其父类OctreePointCloud:int getPointIndicesFromNewVoxels(std:vector&indicesVector_arg,const int minPointsPerLeaf_arg=0)获取缓存区中新添加的叶子节点,indicesVector_arg为新添加的叶子的索引向量,int minPointsPerLeaf_arg设置需要串行化的叶子中应该包含点的最小数目。void setEpsilon(double eps)设置近邻搜索时的误差限。void setInputCloud(const PointCloudConstPtr&cloud_arg,const IndicesConstPtr&indices_arg=IndicesConstPtr()设置输入点云,其中cloud_arg表示输入的点云对象指针,indices_arg表示真正作为输入的点集的索引向量。void setResolution(double resolution_arg)设置八叉树分辨率。void addPointsFromInputCloud()添加利用setInputCloud函数设置的点云到八叉树中。10.class pcl:octree:OctreePointCloudDensity类OctreePointCloudDensity实现了管理一八叉树,其叶子节点并非存储点云,只是对处于其叶子体素中的点云个数进行存储,即整个八叉树的叶子节点存储了输入点云的密度空间分布。类OctreePointCloudDensity关键成员函数,未列出的参考其父类OctreePointCloud:unsigned int getVoxelDensityAtPoint(const PointT&point_arg)const返回point_arg点所在的叶子节点体素的密度,即该点所在的体素中包含点的个数。11.class pcl:octree:OctreePointCloudOccupancy类OctreePointCloudOccupancy实现了管理一八叉树,其叶子节点不存储任何数据,只是对输入点云所占据的空间通过叶子所处的体素来进行标志,这样就可以对点云所占据空间的情况进行评估和检测。类OctreePointCloudOccupancy关键成员函数,未列出的参考其父类OctreePointCloud:void setOccupiedVoxelAtPoint(const PointT&point_arg)在点point_arg所在空间为八叉树添加叶子节点,标识其有点云占据该节点所在体素空间。void setOccupiedVoxelsAtPointsFromCloud(PointCloudPtr cloud_arg)在点集cloud_arg所在空间为八叉树添加叶子节点,标识其有点云占据该节点所在体素空间。12.class pcl:octree:OctreePointCloudPointVector类OctreePointCloudPointVector管理一八叉树,该八叉树叶子节点,存储处在该节点体素中的点对应的索引向量。类OctreePointCloudOccupancy关键成员函数,未列出的参考其父类OctreePointCloud:void setEpsilon(double eps)设置近邻搜索时的误差限。void setInputCloud(const PointCloudConstPtr&cloud_arg,const IndicesConstPtr&indices_arg=IndicesConstPtr()设置输入点云,其中cloud_arg表示输入的点云对象指针,indices_arg表示真正作为输入的点集的索引向量。void setResolution(double resolution_arg)设置八叉树分辨率。13.class pcl:octree:OctreePointCloudSinglePoint类OctreePointCloudSinglePoint管理一八叉树,该八叉树叶子节点,存储处在该节点体素中的单个点的索引,其关键函数参考类OctreePointCloudPointVector。14.class pcl:octree:OctreePointCloudVoxelCentroid类OctreePointCloudVoxelCentroid管理一八叉树,可提供被点云占据节点对应体素的中心点坐标。类OctreePointCloudVoxelCentroid关键成员函数,未列出的参考其父类OctreePointCloud:unsigned int getVoxelCentroids(AlignedPointTVector&voxelCentroidList_arg)返回所有被点云占据的叶子节点的中心点组成的向量,存储在voxelCentroidList_arg中,返回值为返回中心的个数。bool getVoxelCentroidAtPoint(const PointT&point_arg,PointT&voxelCentroid_arg)返回点point_arg对应的节点体素的中心点,存储在voxelCentroid_arg中,返回值为true表示操作成功,否则表示操作失败。bool getVoxelCentroidAtPoint(const int&pointIdx_arg,PointT&voxelCentroid_arg)返回索引pointIdx_arg对应点所代表的节点体素中心点,存储在voxelCentroid_arg中,返回值为true表示成功,否则表示操作失败。15.Class pcl:octree:OctreePointCloudSearch类OctreePointCloudSearch实现了基于八叉树的点云近邻高效搜索。类OctreePointCloudSearch关键成员函数:bool voxelSearch(const PointT&point,std:vector&pointIdx_data)给定查询点point,通过point确定其所在的体素,返回体素中所有点的索引存储在pointIdx_data。bool voxelSearch(const int index,std:vector&pointIdx_data)功能同上函数,区别是查询点通过index指定。int nearestKSearch(const PointCloud&cloud,int index,int k,std:vector&k_indices,std:vector&k_sqr_distances)近邻搜索,cloud为搜索的点云对象,index为查询点的索引,k为搜索返回的近邻个数,k_indices为返回近邻索引向量,k_sqr_distances存储近邻点对应的距离平方向量。int nearestKSearch(const PointT&p_q,int k,std:vector&k_indices,std:vector&k_sqr_distances)功能同上,p_q为指定的查询点,其他参数类似。void approxNearestSearch(const PointCloud&cloud,int query_index,int&result_index,float&sqr_distance)近似近邻搜索,其他参数同上。int radiusSearch(const PointCloud&cloud,int index,double radius,std:vector&k_indices,std:vector&k_sqr_distances,unsigned int max_nn=0)获取查询点radius半径内的近邻点集,cloud为搜索的点云对象,index为查询点的索引,k为搜索返回的近邻个数,k_indices为返回近邻索引向量,k_sqr_distances存储近邻点对应的距离平方向量,max_nn默认为0,如果设置就返回半径内邻域个数上限,返回值为返回领域点的个数。int getIntersectedVoxelCenters(Eigen:Vector3f origin,Eigen:Vector3f direction,AlignedPointTVector&voxelCenterList)const给定经过点origin指向direction的直线,返回与该直线相交的点云对应八叉树的体素中心点组成的向量,并存储在voxelCenterList中,返回值为相交体素个数。int getIntersectedVoxelIndices(Eigen:Vector3f origin,Eigen:Vector3f direction,std:vector&k_indices)const功能同上函数,k_indices存储相交体素的索引。int boxSearch(const Eigen:Vector3f&min_pt,const Eigen:Vector3f&max_pt,std:vector&k_indices)const搜索处于指定立方体内的点集,min_pt、max_pt指定立方体的左前下角坐标及右后上方坐标来定义立方体,k_indices存储落在立方体内的点的索引。void setInputCloud(const PointCloudConstPtr&cloud_arg,const IndicesConstPtr&indices_arg=IndicesConstPtr()指定构建八叉树的点云。void setEpsilon(double eps)设置搜索时的精度。void setResolution(double resolution_arg)设置八叉树的体素分辨率。void addPointsFromInputCloud()显示调用将点云添加到八叉树管理结构中。void addPointFromCloud(const int pointIdx_arg,IndicesPtr indices_arg)添加对应索引中的点到八叉树中,其中pointIdx_arg为索引,indices_arg索引序列的指针。void addPointToCloud(const PointT&point_arg,PointCloudPtr cloud_arg,IndicesPtr indices_arg)添加点point_arg到点云cloud_arg的indices_arg索引下,同时添加到八叉树中。bool isVoxelOccupiedAtPoint(const PointT&point_arg)const判断点point_arg所处的空间是否存在于八叉树体素中。bool isVoxelOccupiedAtPoint(const double pointX_arg,const double pointY_arg,const double pointZ_arg)const判断点(pointX_arg,pointY_arg,pointZ_arg)所处的空间是否存在于八叉树体素中。int getOccupiedVoxelCenters(AlignedPointTVector&voxelCenterList_arg)const返回所有被点云占据的体素的中心存储在voxelCenterList_arg中,返回值为被占据的体素的个数。int getApproxIntersectedVoxelCentersBySegment(const Eigen:Vector3f&origin,const Eigen:Vector3f&end,AlignedPointTVector&voxel_center_list,float precision=.2)用参数origin和end给定空间一线段,该函数求得与该线段相交的体素中心,存储在voxel_center_list,并返回相交体素的个数。void deleteVoxelAtPoint(const PointT&point_arg)删除指定点所在的八叉树中管理的体素或叶子节点。void defineBoundingBox(const double minX_arg,const double minY_arg,const double minZ_arg,const double maxX_arg,const double maxY_arg,const double maxZ_arg)指定八叉树的包围盒,参数为3个维度的上下限,八叉树中一旦存储管理元素了,则包围盒大小就不能再改变。void getBoudingBox(double&minX_arg,double&minY_arg,double&minZ_arg,double&maxX_arg,double&maxY_arg,double&maxZ_arg)const获取包围盒子3个维度的上下限。double getVoxelSquaredDiameter(unsigned int treeDepth_arg)const获取八叉树中指定深度对应体素的内切圆的直径。double getVoxelSquaredSideLen(unsigned int treeDepth_arg)const获取八叉树中指定深度对应体素的立方体的边长。6.3 应用实例解析6.3.1 在在PCL中如何中如何实现点云点云压缩点云由海量的数据集组成,这些数据集通过距离、颜色、法线等附加信息来描述空间三维点。此外,点云能以非常高的速率被创建出来,因此需要占用相当大的存储资源,一旦点云需要存储或者通过速率受限制的通信信道进行传输,提供针对这种数据的压缩方法就变得十分有用。PCL库提供了点云压缩功能,它允许编码压缩所有类型的点云,如图6-3所示,包括“无序”点云,它具有无参考点和变化的点尺寸、分辨率、分布密度和点顺序等结构特征。而且,底层的octree数据结构允许从几个输入源高效地合并点云数据。下面解释单个点云和点云数据流是如何高效压缩的,在给出的例子中用PCL点云压缩技术来压缩用OpenNIGrabber抓取到的点云。在本书提供光盘的第6章例1文件夹中打开名为point_cloud_compression.cpp的代码文件。1.代代码解解释说明明下面详细解析打开的源代码。从主函数开始首先创建一个新的SimpleOpenNIViewer实例并调用它的run()方法。intmain(int argc,char*argv)SimpleOpenNIViewer v;v.run();return(0);在run()函数中创建PointCloudCompression类的对象来编码和解码,这些对象把压缩配置文件作为配置压缩算法的参数,所提供的压缩配置文件为OpenNI兼容设备采集到的点云预先确定的通用参数集。本例中使用MED_RES_ONLINE_COMPRESSION_WITH_COLOR配置参数集,它应用5mm 的编码精度并且允许彩色纹理成分编码,并进一步优化,用于快速在线压缩。压缩配置文件的完整列表及其配制方法可以在文件“/io/include/pcl/compression/compression_profiles.h”中找到。在PointCloudCompression构造函数中使用MANUAL_CONFIGURATION属性就可以手动设置压缩算法全部参数。bool showStatistics=true;/设置在标准设备上输出打印出压缩结果信息/压缩选项详见/io/include/pcl/compression/compression_profiles.h3pcl:octree:compression_Profiles_e compressionProfile=pcl:octree:MED_RES_ONLINE_COMPRESSION_WITH_COLOR;/初始化压缩与解压缩对象,其中压缩对象需要设定压缩参数选项,解压缩按照数据源自行判断pointCloudEncoder=new pcl:octree:PointCloudCompression(compressionProfile,showStatistics);pointCloudDecoder=new pcl:octree:PointCloudCompression();下面的代码为OpenNI兼容设备实例化一个新的采集器,并且启动循环回调接口,每从设备获取一帧数据就调用回调函数一次,这里的回调函数实现数据压缩和可视化解压缩结果。/创建从OpenNI获取点云的抓取对象pcl:Grabber*interface=new pcl:OpenNIGrabber();boost:functionvoid(const pcl:PointCloud:ConstPtr&)f=boost:bind(&SimpleOpenNIViewer:cloud_cb_,this,_1);/建立回调函数/建立回调函数与回调信号之间绑定boost:signals2:connection c=interface-registerCallback(f);/开始接收点云数据流interface-start();while(!viewer.wasStopped()sleep(1);interface-stop();在OpenNIGrabber采集循环执行的回调函数cloud_cb_中,首先把获取到的点云压缩到stringstream缓冲区,下一步是解压缩,它对压缩了的二进制数据进行解码,存储在新的点云对象中,解码了的点云被发送到点云可视化对象中进行实时可视化。void cloud_cb_(const pcl:PointCloud:ConstPtr&cloud)if(!viewer.wasStopped()std:stringstream compressedData;/存储压缩点云的字节流对象pcl:PointCloud:PtrcloudOut/存储输出点云(new pcl:PointCloud();PointCloudEncoder-encodePointCloud(cloud,compressedData);/压缩点云PointCloudDecoder-decodePointCloud(compressedData,cloudOut);/解压缩点云viewer.showCloud(cloudOut);/可视化解压缩点云/在压缩与解压缩过程中,因为设置compressedData为true所以在标准输出上打印出压缩率帧数等信息2.编译并运行并运行该程序程序利用光盘提供的CMakeLists.txt文件,在CMake中建立工程文件并生成相应的可执行文件,生成执行文件后,就可以运行了,在CMD中键入命令:point_cloud_compression.exe可以看到图6-4所示结果,左边为带有RGB纹理信息的实时可视化结果,用户缩放可视化结果可以看到经过压缩后点云进行了重采样,纹理信息有所丢失,但数据量有所减小,在实际应用中需折中取舍。右边则为实时压缩信息输出,可以看出压缩的帧数、点数、压缩率等信息。3.压缩配置文件配置文件压缩配置文件为PCL点云编码器定义了参数集,并针对压缩从OpenNI采集器获取的普通点云进行了优化设置。注意,解码对象不需要用参数表示,因为它在解码时检测并获取对应的编码参数配置。下面的压缩配置文件是可用的:LOW_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率1cm,无颜色,快速在线编码LOW_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率1cm ,有颜色,快速在线编码MED_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率5mm ,无颜色,快速在线编码MED_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率5mm,有颜色,快速在线编码HIGH_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率1mm,无颜色,快速在线编码HIGH_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率1mm,有颜色,快速在线编码333333LOW_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率1cm ,无颜色,高效离线编码LOW_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率1cm ,有颜色,高效离线编码MED_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率5mm,无颜色,高效离线编码MED_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率5mm,有颜色,高效离线编码HIGH_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率5mm ,无颜色,高效离线编码HIGH_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率5mm ,有颜色,高效离线编码MANUAL_CONFIGURATION允许为高级参数化进行手工配置。3333334.高高级参数化参数化为了能完全控制压缩相关的参数,PointCloudCompression类的构造函数可以在初始化时附加压缩参数。请注意,为了启用高级参数化,compressionProfile_arg参数需要被设置成MANUAL_CONFIGURATION。PointCloudCompression(compression_Profiles_e compressionProfile_arg,bool showStatistics_arg,const double pointResolution_arg,const double octreeResolution_arg,bool doVoxelGridDownDownSampling_arg,const unsigned intiFrameRate_arg,bool doColorEncoding_arg,const unsigned char colorBitResolution_arg)下面解释高级参数化设置:compressionProfile_arg:为了启用高级参数化,该参数应该被设置成MANUAL_CONFIGURATION。showStatistics_arg:把压缩相关的统计信息打印到标准输出。pointResolution_arg:定义点坐标的编码精度,该参数应该设置成小于传感器精度的一个值。octreeResolution_arg:该参数定