路由下做网站映射,我的世界是怎么做的视频网站,`北京网站建设,做网站赚50万一、什么是Octree 八叉树#xff08;Octree#xff09;是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素#xff0c;每个节点有八个子节点#xff0c;这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中…一、什么是Octree 八叉树Octree是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素每个节点有八个子节点这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。且每个节点可以继续分割直到满足某个条件如达到最大深度或最小点数。这种结构特别适合于稀疏点云数据的处理能够高效地进行空间查询和操作。
实现八叉树的原理 (1). 设定最大递归深度。 (2). 找出场景的最大尺寸并以此尺寸建立第一个立方体。 (3). 依序将单位元元素丢入能被包含且没有子节点的立方体。 (4). 若没达到最大递归深度就进行细分八等份再将该立方体所装的单位元元素全部分担给八个子立方体。 (5). 若发现子立方体所分配到的单位元元素数量不为零且跟父立方体是一样的则该子立方体停止细分因为跟据空间分割理论细分的空间所得到的分配必定较少若是一样数目则再怎么切数目还是一样会造成无穷切割的情形。 (6). 重复3直到达到最大递归深度。
二、八叉树应用
1、点云压缩 点云由巨大的数据集组成这些数据集描述了三维点并与诸如距离、颜色、法线等附加信息相关联。此外它们可以以很高的速率创建因此占用大量的内存资源。一旦点云必须在速率有限的通信信道上存储或传输压缩这类数据的方法就变得非常有趣了。 点云库提供点云压缩功能。它允许编码所有类型的点云包括无序的点云其特征是不存在的点引用不同的点大小分辨率密度和/或点顺序。 此外底层八叉树数据结构能够有效地合并来自多个来源的点云数据。 以下示例演示如何有效地压缩单点云以及点云流。
压缩单点云 几何压缩 Octree编码将空间分割成八个子区域递归进行直到每个节点包含的点数少于某个阈值。使用八叉树结构可以有效减少存储需求。KD树编码通过平衡树结构将点云分割并按层次顺序存储可以较好地压缩数据。 基于变换的压缩 主成分分析 (PCA)对点云数据进行主成分分析将点云数据投影到主成分上减少维度从而达到压缩的目的。离散余弦变换 (DCT) 和 小波变换将点云数据转变到频域利用能量集中在低频部分的特性舍弃高频部分实现压缩。 点位置编码 量化将点的坐标值进行量化可以在一定程度上减少数据量。预测编码使用点的邻域信息预测当前点的位置仅存储预测误差从而减少存储量。
压缩点云流 时间冗余压缩 帧间差分编码仅存储相邻帧之间的差异而不是每一帧的完整数据。可以大大减少数据量。运动估计和补偿通过估计点云流中的运动矢量只存储运动矢量和补偿信息。 基于模型的压缩 动态几何模型利用物体的运动模型如刚体运动模型、骨架动画等来预测点的位置只存储模型参数。稀疏表示使用稀疏矩阵或张量表示点云流存储非零元素及其索引。 空间和时间联合压缩 四维3D空间时间Octree编码将时间维度加入Octree结构实现空间和时间的联合压缩。时空小波变换对点云流进行时空小波变换利用点云流在时空域的稀疏性进行压缩。 机器学习方法 自编码器使用神经网络的自编码器结构学习点云数据的低维表示从而实现压缩。生成对抗网络GANs利用GAN生成逼真的点云数据可以仅存储生成器的模型参数而不是所有点数据。
示例一进行压缩和解压缩
#include iostream
#include pcl/point_types.h
#include pcl/io/pcd_io.h
#include pcl/io/octree_pointcloud_compression.hint main(int argc, char** argv) {// 创建一个点云对象pcl::PointCloudpcl::PointXYZRGBA::Ptr cloud(new pcl::PointCloudpcl::PointXYZRGBA());pcl::PointCloudpcl::PointXYZRGBA::Ptr cloudOut(new pcl::PointCloudpcl::PointXYZRGBA());// 生成一些示例点云数据cloud-width 100;cloud-height 1;cloud-points.resize(cloud-width * cloud-height);for (size_t i 0; i cloud-points.size(); i) {cloud-points[i].x 1024 * rand() / (RAND_MAX 1.0f);cloud-points[i].y 1024 * rand() / (RAND_MAX 1.0f);cloud-points[i].z 1024 * rand() / (RAND_MAX 1.0f);cloud-points[i].r rand() % 256;cloud-points[i].g rand() % 256;cloud-points[i].b rand() % 256;cloud-points[i].a 255;}// 初始化点云压缩和解压缩对象pcl::io::compression_Profiles_e compressionProfile pcl::io::HIGH_RES_ONLINE_COMPRESSION_WITHOUT_COLOR;bool showStatistics true;pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA PointCloudEncoder(compressionProfile, showStatistics);pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA PointCloudDecoder;// 压缩点云std::stringstream compressedData;PointCloudEncoder.encodePointCloud(cloud, compressedData);// 解压缩点云PointCloudDecoder.decodePointCloud(compressedData, cloudOut);// 打印压缩和解压缩后的点云数据std::cout Original Point Cloud: std::endl;for (size_t i 0; i cloud-points.size(); i) {std::cout cloud-points[i] std::endl;}std::cout Decompressed Point Cloud: std::endl;for (size_t i 0; i cloudOut-points.size(); i) {std::cout cloudOut-points[i] std::endl;}return 0;
}示例二OpenNI兼容设备
下面的代码为OpenNI兼容设备实例化一个新的采样器并且启动循环回调接口每从设备获取一帧数据就回调函数一次这里的回调函数就是实现数据压缩和可视化解压缩结果。
出处PCL学习八叉树 - Being_young - 博客园 (cnblogs.com)
#include pcl/point_cloud.h // 点云类型
#include pcl/point_types.h //点数据类型
#include pcl/io/openni_grabber.h //点云获取接口类
#include pcl/visualization/cloud_viewer.h //点云可视化类#include pcl/compression/octree_pointcloud_compression.h //点云压缩类#include stdio.h
#include sstream
#include stdlib.h#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endifclass SimpleOpenNIViewer
{
public:SimpleOpenNIViewer () :viewer ( Point Cloud Compression Example){}
/************************************************************************************************在OpenNIGrabber采集循环执行的回调函数cloud_cb_中首先把获取的点云压缩到stringstream缓冲区下一步就是解压缩它对压缩了的二进制数据进行解码存储在新的点云中解码了点云被发送到点云可视化对象中进行实时可视化
*************************************************************************************************/void cloud_cb_ (const pcl::PointCloudpcl::PointXYZRGBA::ConstPtr cloud){if (!viewer.wasStopped ()){// 存储压缩点云的字节流对象std::stringstream compressedData;// 存储输出点云pcl::PointCloudpcl::PointXYZRGBA::Ptr cloudOut (new pcl::PointCloudpcl::PointXYZRGBA ());// 压缩点云PointCloudEncoder-encodePointCloud (cloud, compressedData);// 解压缩点云PointCloudDecoder-decodePointCloud (compressedData, cloudOut);// 可视化解压缩的点云viewer.showCloud (cloudOut);}}
/**************************************************************************************************************在函数中创建PointCloudCompression类的对象来编码和解码这些对象把压缩配置文件作为配置压缩算法的参数所提供的压缩配置文件为OpenNI兼容设备采集到的点云预先确定的通用参数集本例中使用MED_RES_ONLINE_COMPRESSION_WITH_COLOR配置参数集用于快速在线的压缩压缩配置方法可以在文件/io/include/pcl/compression/compression_profiles.h中找到在PointCloudCompression构造函数中使用MANUAL——CONFIGURATION属性就可以手动的配置压缩算法的全部参数
******************************************************************************************************************/void run (){bool showStatistics true; //设置在标准设备上输出打印出压缩结果信息// 压缩选项详情在: /io/include/pcl/compression/compression_profiles.hpcl::io::compression_Profiles_e compressionProfile pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;// 初始化压缩和解压缩对象 其中压缩对象需要设定压缩参数选项解压缩按照数据源自行判断PointCloudEncoder new pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA (compressionProfile, showStatistics);PointCloudDecoder new pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA ();/***********************************************************************************************************下面的代码为OpenNI兼容设备实例化一个新的采样器并且启动循环回调接口每从设备获取一帧数据就回调函数一次这里的回调函数就是实现数据压缩和可视化解压缩结果。************************************************************************************************************///创建从OpenNI获取点云的抓取对象pcl::Grabber* interface new pcl::OpenNIGrabber ();// 建立回调函数boost::functionvoid(const pcl::PointCloudpcl::PointXYZRGBA::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 ();// 删除压缩与解压缩的实例delete (PointCloudEncoder);delete (PointCloudDecoder);}pcl::visualization::CloudViewer viewer;pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA* PointCloudEncoder;pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA* PointCloudDecoder;};int
main (int argc, char **argv)
{SimpleOpenNIViewer v; //创建一个新的SimpleOpenNIViewer 实例并调用他的run方法v.run ();return (0);
}
示例三官方demo
#include pcl/point_cloud.h
#include pcl/point_types.h
#include pcl/io/openni_grabber.h
#include pcl/visualization/cloud_viewer.h#include pcl/compression/octree_pointcloud_compression.h#include stdio.h
#include sstream
#include stdlib.h#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endifclass SimpleOpenNIViewer
{
public:SimpleOpenNIViewer () :viewer ( Point Cloud Compression Example){}voidcloud_cb_ (const pcl::PointCloudpcl::PointXYZRGBA::ConstPtr cloud){if (!viewer.wasStopped ()){// stringstream to store compressed point cloudstd::stringstream compressedData;// output pointcloudpcl::PointCloudpcl::PointXYZRGBA::Ptr cloudOut (new pcl::PointCloudpcl::PointXYZRGBA ());// compress point cloudPointCloudEncoder-encodePointCloud (cloud, compressedData);// decompress point cloudPointCloudDecoder-decodePointCloud (compressedData, cloudOut);// show decompressed point cloudviewer.showCloud (cloudOut);}}voidrun (){bool showStatistics true;// for a full list of profiles see: /io/include/pcl/compression/compression_profiles.hpcl::io::compression_Profiles_e compressionProfile pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;// instantiate point cloud compression for encoding and decodingPointCloudEncoder new pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA (compressionProfile, showStatistics);PointCloudDecoder new pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA ();// create a new grabber for OpenNI devicespcl::Grabber* interface new pcl::OpenNIGrabber ();// make callback function from member functionstd::functionvoid(const pcl::PointCloudpcl::PointXYZRGBA::ConstPtr) f [this] (const pcl::PointCloudpcl::PointXYZRGBA::ConstPtr cloud) { cloud_cb_ (cloud); };// connect callback function for desired signal. In this case its a point cloud with color valuesboost::signals2::connection c interface-registerCallback (f);// start receiving point cloudsinterface-start ();while (!viewer.wasStopped ()){sleep (1);}interface-stop ();// delete point cloud compression instancesdelete (PointCloudEncoder);delete (PointCloudDecoder);}pcl::visualization::CloudViewer viewer;pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA* PointCloudEncoder;pcl::io::OctreePointCloudCompressionpcl::PointXYZRGBA* PointCloudDecoder;};int
main ()
{SimpleOpenNIViewer v;v.run ();return (0);
}
2、空间分区与点云检索 下篇文章单独讲检索
3、点云数据空间变换检测
官网demoSpatial change detection on unorganized point cloud data — Point Cloud Library 0.0 documentationhttps://pcl.readthedocs.io/projects/tutorials/en/latest/octree_change.html#octree-change-detection
八叉树是一种基于树的数据结构用于组织稀疏的三维数据。在本demo中我们将学习如何使用八叉树实现来检测多个无组织点云之间的空间变化这些变化可能在大小分辨率密度和点顺序上有所不同。变换检测主要用于检测点云数据中不同时间点之间的变化。这种变化检测在很多实际应用场景中非常有用特别是需要监控环境变化或检测动态物体的领域即识别到场景中物体的变换。
通过递归比较八叉树的树结构可以识别由体素配置差异所代表的空间变化。
此外我们解释了如何使用pcl八叉树“双缓冲”技术使我们能够随着时间的推移有效地处理多个点云。
3.1 示例
#include pcl/point_cloud.h
#include pcl/point_types.h
#include pcl/octree/octree_pointcloud_changedetector.h
#include iostreamint main() {// 定义点云类型typedef pcl::PointXYZ PointT;// 创建两个点云pcl::PointCloudPointT::Ptr cloudA(new pcl::PointCloudPointT);pcl::PointCloudPointT::Ptr cloudB(new pcl::PointCloudPointT);// 添加点到第一个点云 (cloudA)cloudA-push_back(PointT(1.0, 1.0, 1.0));cloudA-push_back(PointT(1.0, 2.0, 1.0));cloudA-push_back(PointT(1.0, 3.0, 1.0));// 添加点到第二个点云 (cloudB)cloudB-push_back(PointT(1.0, 1.0, 1.0));cloudB-push_back(PointT(1.0, 2.0, 1.0));cloudB-push_back(PointT(1.0, 3.0, 1.0));cloudB-push_back(PointT(1.0, 4.0, 1.0)); // 新增点// 创建八叉树变化检测器设置分辨率float resolution 0.5f;pcl::octree::OctreePointCloudChangeDetectorPointT octree(resolution);// 将第一个点云 (cloudA) 添加到八叉树中octree.setInputCloud(cloudA);octree.addPointsFromInputCloud();// 切换到第二个点云 (cloudB)octree.switchBuffers();octree.setInputCloud(cloudB);octree.addPointsFromInputCloud();// 获取变化检测结果std::vectorint newPointIdxVector;octree.getPointIndicesFromNewVoxels(newPointIdxVector);// 输出变化点的索引和坐标std::cout Points added in cloudB: std::endl;for (std::size_t i 0; i newPointIdxVector.size(); i) {std::cout Index: newPointIdxVector[i] , Point: cloudB-points[newPointIdxVector[i]].x cloudB-points[newPointIdxVector[i]].y cloudB-points[newPointIdxVector[i]].z std::endl;}return 0;
}3.2 解释
定义点云类型使用 pcl::PointXYZ 作为点云的点类型创建点云创建两个点云 cloudA 和 cloudB 并向其中添加点创建八叉树变化检测器使用 pcl::octree::OctreePointCloudChangeDetector 创建八叉树变化检测器并设置分辨率。分辨率决定了八叉树的叶子节点大小即检测变化的精度添加第一个点云到八叉树中将第一个点云cloudA添加到八叉树中切换缓冲区调用 switchBuffers 方法这样八叉树会保存之前点云的状态并准备接收新的点云数据。 OctreePointCloudChangeDetector类继承自Octree2BufBase类后者能够同时在内存中保持和管理两个八树。此外它实现了一个内存池可以重用已经分配的节点对象从而在生成多点云的八叉树时减少昂贵的内存分配和释放操作。通过调用 octree. switchbuffers() 重置了八叉树类同时在内存中保留了之前的八叉树结构。
添加第二个点云到八叉树中将第二个点云cloudB添加到八叉树中。获取变化检测结果调用 getPointIndicesFromNewVoxels 方法获取在第二个点云中新增的点的索引。 为了检索存储在当前八叉树结构(基于cloudB)体素上的点这些点在之前的八叉树结构(基于cloudA)中不存在我们可以调用“getPointIndicesFromNewVoxels”方法该方法返回结果点索引的向量。
输出变化点遍历新点的索引并输出它们的坐标。 三、接口文档学习
pcl_octree库提供了从点云数据创建分层树数据结构的有效方法。这允许对点数据集进行空间分区、下采样和搜索操作。每个八叉树节点要么有八个子节点要么没有子节点。根节点描述了一个立方体边界框它封装了所有的点。在每个树级别该空间被细分为2倍从而提高体素分辨率。
pcl_octree实现提供了高效的最近邻搜索例程如“体素内邻居搜索”、“K近邻搜索”和“半径内邻居搜索”。它会根据点数据集自动调整其尺寸。一组叶节点类提供了额外的功能例如空间“占用”和“每体素点密度”检查。序列化和反序列化函数能够有效地将八叉树结构编码为二进制格式。此外在需要高速创建八叉树的场景中内存池实现减少了昂贵的内存分配和释放操作。 1、Octree模块主要类 pcl::octree::OctreePointCloudT 功能这是 Octree 模块的基类提供了基本的八叉树结构和功能包括树的构建、插入、删除等操作。主要子类 pcl::octree::OctreePointCloudSinglePointTpcl::octree::OctreePointCloudPointVectorTpcl::octree::OctreePointCloudVoxelCentroidT pcl::octree::OctreePointCloudSinglePointT 功能此类继承自 OctreePointCloudT用于每个八叉树节点存储单个点。 pcl::octree::OctreePointCloudPointVectorT 功能此类继承自 OctreePointCloudT用于每个八叉树节点存储一个点向量多个点。 pcl::octree::OctreePointCloudVoxelCentroidT 功能此类继承自 OctreePointCloudT用于每个八叉树节点存储体素Voxel质心。 pcl::octree::OctreePointCloudSearchT 功能提供搜索功能包括邻域搜索、半径搜索和 K 近邻搜索等。继承自 OctreePointCloudPointVectorT。 pcl::octree::OctreePointCloudCompressionT 功能用于点云数据的压缩和解压缩利用八叉树结构来减少数据存储需求。
2、类之间的关系
OctreePointCloudT 是 Octree 模块的基类其他类通过继承自它来实现不同的功能。具体关系如下
pcl::octree::OctreePointCloudT基类定义了基本的八叉树操作。 pcl::octree::OctreePointCloudSinglePointT继承自 OctreePointCloudT每个节点存储一个点。pcl::octree::OctreePointCloudPointVectorT继承自 OctreePointCloudT每个节点存储一个点向量。pcl::octree::OctreePointCloudVoxelCentroidT继承自 OctreePointCloudT每个节点存储一个体素质心。pcl::octree::OctreePointCloudSearchT继承自 OctreePointCloudPointVectorT提供搜索功能。pcl::io::OctreePointCloudCompressionT独立实现但依赖 Octree 结构进行压缩和解压缩。