kdTree相关原理及c++实现
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++实现的更多相关文章
- KdTree && Octree 原理学习对比以及可视化分析--"索引树"
1. Kdtree 原理 k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索): 索引结构中相似性查询有两种基 ...
- 常见的GAN网络的相关原理及推导
常见的GAN网络的相关原理及推导 在上一篇中我们给大家介绍了GAN的相关原理和推导,GAN是VAE的后一半,再加上一个鉴别网络.这样而导致了完全不同的训练方式. GAN,生成对抗网络,主要有两部分构成 ...
- Kd-tree算法原理
参考资料: Kd Tree算法原理 Kd-Tree,即K-dimensional tree,是一棵二叉树,树中存储的是一些K维数据.在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成 ...
- Kd-Tree算法原理和开源实现代码
本文介绍一种用于高维空间中的高速近期邻和近似近期邻查找技术--Kd-Tree(Kd树). Kd-Tree,即K-dimensional tree,是一种高维索引树形数据结构,经常使用于在大规模的高维数 ...
- ssh相关原理学习与常见错误总结
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...
- 从矩阵(matrix)角度讨论PCA(Principal Component Analysis 主成分分析)、SVD(Singular Value Decomposition 奇异值分解)相关原理
0. 引言 本文主要的目的在于讨论PAC降维和SVD特征提取原理,围绕这一主题,在文章的开头从涉及的相关矩阵原理切入,逐步深入讨论,希望能够学习这一领域问题的读者朋友有帮助. 这里推荐Mit的Gilb ...
- HOOK相关原理与例子
消息HOOK 原理: 1. 用户输入消息,消息被放到系统消息队列. 2. 程序发生了某些需要获取输入的事件,就从系统消息队列拿出消息放到程序消息队列中. 3. 应用程序检测到有新的消息进入到程序消息队 ...
- composer安装及使用说明和相关原理文档
一.安装composer: 1.官方安装方法见https://getcomposer.org/download/ 2.本人安装方法: ①先配好yum源(不会配置的见博客如何制作自己的yum源),我 ...
- View的相关原理(读书笔记)
View的使用方法相关: 1.setContentView() 2.LayoutInflater.inflate() PS:本质上setContentView()方法最终也是通过LayoutInfla ...
随机推荐
- nodejs的__dirname,__filename,process.cwd()区别
假定我们有这样一个mynode的node项目在User/leinov/porject/文件夹下,cli是一个可执行文件 |-- mynode |-- bin |-- cli.js |-- src |- ...
- MVC删除操作前confirm提示
本段时间,忙于公司的ERP问题,博客也没有怎样更新了.昨晚于家中学习了MVC时,对删除记录前,让用户有后悔选择.即是说,能先给用户一个提示,然后再让用户决定是否删除记录.以前练习MVC,对删除记录,均 ...
- node.js遇到的问题
1.cann't find module 'request' 不能找到’request' 模块 解决方法:找到项目的根路径,cd到该路径,运行命令 npm install request 2.no ...
- 月赛 && SX_ACM 惨痛教训
1.cnt变量若有多次询问,一定要记得初始化!!! 2.多组数据输出入,区泛~. 3.高性能问题,考虑位运算,
- Java使用递归的方法进行冒泡排序
对于递归来说,我只了解它的概念,没有具体使用过,近期也是尝试着用递归写了一下冒泡排序和大家分享,希望能帮助大家了解递归 递归是什么?通俗的讲:在方法内部调用自己 花了几分钟整出来的,下面是递归冒泡排序 ...
- Okhttp3 使用和原理(DEMO)
基本使用: http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html http://www.jianshu.c ...
- 如何在SpringMVC中使用REST风格的url
如何在SpringMVC中使用REST风格的url 1.url写法: get:/restUrl/{id} post:/restUrl delete:/restUrl/{id} put:/restUrl ...
- C# Task注意事项
1.在Task中调用主线程控件 Task.Factory.StartNew(() => { }).ContinueWith(task => { this.Invoke(new Action ...
- JavaSE——线程调度
线程调度: 按照特定机制为线程分配cpu的使用权. 线程调度模型: 分时调度 所有线程轮流获得cpu的使用权,平均分配每个线程占用的cpu的时间片. 抢占时调度(java虚拟机) 可运行池中优先级高的 ...
- JavaSE——多线程实现的两种方式
Thread类: 创建新执行线程有两种方法. 一种方法是将类声明为 Thread 的子类.该子类应重写 Thread 类的 run 方法.接下来可以分配并启动该子类的实例.例如,计算大于某一规定值的质 ...