kdTree概念

kd-tree或者k维树是计算机科学中使用的一种数据结构,用来组织表示k维空间中点的集合。它是一种带有其他约束条件的二分查找树。Kd-tree对于区间和近邻搜索十分有用。一般位于三维空间中的邻域搜索常用kd-tree,因此本文中所有的kd-tree都是三维的kd-tree。

图一

Kd-tree也是二叉树的一种,首先我们先选定一个维度用于第一次分类,如图一所示,我们先选择x维度方向作为分类方向,随机选取一个值使得小于该值的点位于左边,大于该值的点位于右边。在左右区域分别再对第二个维度进行分类,这里以y轴方向作为第二维度,同理根据y分类设置z轴方向为第三维度进行分类。

Kd-tree数据结构定义

Node-data:数据矢量,数据集中某个数据点,是n维矢量(总维度,unsigned int)

Range:空间矢量,该节点所代表的的空间范围(二维数组)

Split:整数,垂直于分割超平面的方向轴序号(int)

Left:k-d树,由位于该节点分割超平面左侧子空间内所有点构成的k-d树(tuple<list,int>)

Right:k-d树,由位于该节点分割超平面右侧子空间内所有点构成的k-d树(tuple<list,int>)

Parent:k-d树,父节点(auto)

Kd-tree优化

方案一:Kd-tree通过不同维度划分数据,节点的选择显得尤为重要。我们可以想象一组点云,并不是完全随机离散的,只在某一维度上点云分布较为离散,其余维度相对集中。以三维空间为例,一组类似球状的点云在求每个方向的子节点能保证效率是最高的,但是数据接近一个平面时,在其中一个维度的划分就显得十分困难。

解决方法:首先,对于点云分布不集中的那一维度来说,方差较大,我们可以通过最大方差法选择每次需要分类的维度,即在每次进行新的划分之前,我们通过判断方差选择在哪个维度上进行划分。

方案二:为了保证每次选择的节点尽量位于中间位置,也就是让二叉树尽量为二叉平衡树,从而保证节点两侧的点云数目大致相等。

解决方法:在选取节点前,我们对数据进行排序,选取中位数作为节点,这样就能保证两侧数据大致相等。

PCL库c++源码

 #include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/impl/kdtree_flann.hpp>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/kdtree/io.h>
#include <pcl/kdtree/flann.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/impl/io.hpp>
#include <pcl/search/flann_search.h>
#include <pcl/surface/gp3.h>
//#include <pcl/visualization/pcl_visualizer.h> int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr inCloud(new pcl::PointCloud<pcl::PointXYZ>);
//construct a plane, the equation is x + y + z = 1
for (float x = -1.0; x <= 1.0; x += 0.005)
{
for (float y = -1.0; y <= 1.0; y += 0.005)
{
pcl::PointXYZ cloud; cloud.x = x;
cloud.y = y;
cloud.z = - x - y; inCloud->push_back(cloud);
}
} pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
pcl::PointCloud<pcl::Normal>::Ptr pcNormal(new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud(inCloud);
ne.setInputCloud(inCloud);
ne.setSearchMethod(tree);
ne.setKSearch();
//ne->setRadiusSearch (0.03);
ne.compute(*pcNormal); pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointXYZINormal>);
pcl::concatenateFields(*inCloud, *pcNormal, *cloud_with_normals); pcl::io::savePCDFile("plane_cloud_out.pcd", *cloud_with_normals); return ;
}

【 结束 】

kdTree相关原理及c++实现的更多相关文章

  1. KdTree && Octree 原理学习对比以及可视化分析--"索引树"

    1. Kdtree 原理 k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索): 索引结构中相似性查询有两种基 ...

  2. 常见的GAN网络的相关原理及推导

    常见的GAN网络的相关原理及推导 在上一篇中我们给大家介绍了GAN的相关原理和推导,GAN是VAE的后一半,再加上一个鉴别网络.这样而导致了完全不同的训练方式. GAN,生成对抗网络,主要有两部分构成 ...

  3. Kd-tree算法原理

    参考资料: Kd Tree算法原理 Kd-Tree,即K-dimensional tree,是一棵二叉树,树中存储的是一些K维数据.在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成 ...

  4. Kd-Tree算法原理和开源实现代码

    本文介绍一种用于高维空间中的高速近期邻和近似近期邻查找技术--Kd-Tree(Kd树). Kd-Tree,即K-dimensional tree,是一种高维索引树形数据结构,经常使用于在大规模的高维数 ...

  5. ssh相关原理学习与常见错误总结

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  6. 从矩阵(matrix)角度讨论PCA(Principal Component Analysis 主成分分析)、SVD(Singular Value Decomposition 奇异值分解)相关原理

    0. 引言 本文主要的目的在于讨论PAC降维和SVD特征提取原理,围绕这一主题,在文章的开头从涉及的相关矩阵原理切入,逐步深入讨论,希望能够学习这一领域问题的读者朋友有帮助. 这里推荐Mit的Gilb ...

  7. HOOK相关原理与例子

    消息HOOK 原理: 1. 用户输入消息,消息被放到系统消息队列. 2. 程序发生了某些需要获取输入的事件,就从系统消息队列拿出消息放到程序消息队列中. 3. 应用程序检测到有新的消息进入到程序消息队 ...

  8. composer安装及使用说明和相关原理文档

    一.安装composer: 1.官方安装方法见https://getcomposer.org/download/   2.本人安装方法: ①先配好yum源(不会配置的见博客如何制作自己的yum源),我 ...

  9. View的相关原理(读书笔记)

    View的使用方法相关: 1.setContentView() 2.LayoutInflater.inflate() PS:本质上setContentView()方法最终也是通过LayoutInfla ...

随机推荐

  1. [Luogu 2656] 采蘑菇

    Description 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖和ZYR经过某条小径一次,可以采 ...

  2. 使用JavaScript实现ajax

    实现ajax之前必须要创建一个 XMLHttpRequest 对象.如果不支持创建该对象的浏览器,则需要创建 ActiveXObject.具体方法如下: var xmlHttp;  function ...

  3. springboot自定义banner生成器

    http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20

  4. 胜利大逃亡(续)hdu1429(bfs)

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. Retrofit 2.0 使用和原理

    使用教程: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/1016/3588.html retrofit2 与okhttp关系 ...

  6. RocketMQ 消息存储

    消息存储 主要的存储文件: 1.消息文件(commitLog) 2.消息消费队列文件(consumeQueue) 3.Hash索引文件(IndexFile) 4.检测点文件(checkpoint) 5 ...

  7. springboot学习-springboot使用spring-data-jpa操作MySQL数据库

    我们在上一篇搭建了一个简单的springboot应用,这一篇将介绍使用spring-data-jpa操作数据库. 新建一个MySQL数据库,这里数据库名为springboot,建立user_info数 ...

  8. ZOJ3209(KB3-B DLX)

    Treasure Map Time Limit: 2 Seconds      Memory Limit: 32768 KB Your boss once had got many copies of ...

  9. Angular4.+ ngx-bootstrap Pagination 自定义分页组件

    Angular4 随笔(二)  ——自定义分页组件 1.简介 本组件主要是实现了分页组件显示功能,通过使用 ngx-bootstrap Pagination分页组件实现. 基本逻辑: 1.创建一个分页 ...

  10. javascript:类数组 -- 对象

    在javascript中,对象与数组都是这门语言的原生规范中的基本数据类型,处于并列的位置. 类数组:本质是一个对象,只是这个 对象  的属性有点特殊,模拟出数组的一些特性. 一般来说,如果我们有一个 ...