PCL之kd-tree详解
前情提要:PCL安装与测试
PCL文件读写
斯坦福兔子文件
kd,即k-dimension,kd树就是k维树,由于点云所在空间几乎都是三维的,所以最常见的也是3d树。
考虑到演示方便,所以用二维空间中的数据来做一点说明,假设现有六个数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}
,如何能够通过这六个点将空间分割,就如下图一样。
当然上面这个图只是一种方案,或许还有其他的划分方式。
对此例来说,其分割步骤为
- 计算x,y方向上数据的标准差,可得sx≈2.4,sy≈2.1s_x\approx2.4,s_y\approx2.1sx≈2.4,sy≈2.1,即sx>xys_x>x_ysx>xy,所以先分割x方向的数据。
- x轴方向的值为2,5,9,4,8,7,排序后为2,4,5,7,8,9,中值为7,所以先在x=7x=7x=7的位置画一条与y轴平行的线,这条线经过点(7,2),将平面分成左子空间和右子空间。
- x⩽7x\leqslant7x⩽7的左子空间,包含3个节点{(2,3), (5,4), (4,7)};x>7x>7x>7的右子空间,则包含2个节点{(9,6),(8,1)}。
- 对左子空间和右子空间重复1过程,直到所有的点都画了线,最终就得到上图了。
而这个生成分割图的过程,也是生成kd树的过程,其树图为
在算法导论中,树往往是和查找挂钩的,kd树亦然,可用于查找与目标点最近的点。
例如要查询点(3,3)(3,3)(3,3),则其步骤为
- 和点(7,2)(7,2)(7,2)比较xxx坐标大小,由于3<73<73<7,故在其左子节点;如果在平面图中看,则在x=7x=7x=7的左子区间。
- 进入左子节点后,和(5,4)(5,4)(5,4)比较yyy值大小,由于3<43<43<4,故继续比较左子节点;如果在平面图中比较,则在y=4y=4y=4的下子区间。
- 由于(5,4)(5,4)(5,4)的左子节点只有一个,所以距离(3,3)(3,3)(3,3)最近的点就是(2,3)(2,3)(2,3)。
在PCL
中生成kd-tree,只需通过setInputCloud
建立搜索空间,便能借助kd树的速度来进行临近点索引,接下来仍然以兔子为例,试用一下PCL中的两个搜索函数nearestKSearch
和radiusSearch
,前者指明最近的K
个点;后者搜索出距离目标小于r
的点。
#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/common/common.h> //getMinMax3D函数需要用到
#include <pcl/kdtree/kdtree_flann.h> //kdtree类定义头文件using namespace pcl;
using namespace std;void randomPoint(PointXYZ *pSearch, PointXYZ pMin, PointXYZ pMax) {pSearch->x = rand()/RAND_MAX * (pMax.x - pMin.x) + pMin.x;pSearch->y = rand()/ RAND_MAX * (pMax.x - pMin.x) + pMin.y;pSearch->z = rand()/ RAND_MAX * (pMax.x - pMin.x) + pMin.z;cout << "the point ("<< pSearch->x << " " << pSearch->y << " " << pSearch->z<< ") will be searched" <<endl;
}void kdTest() {PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);char strfilepath[256] = "rabbit.pcd";io::loadPCDFile(strfilepath, *cloud);KdTreeFLANN<PointXYZ> kdtree; //建立kd treekdtree.setInputCloud(cloud); //设置搜索空间PointXYZ pSearch, pMin, pMax; //搜索点,三个轴的最大值和最小值getMinMax3D(*cloud, pMin, pMax); //需要include<pcl/common/common.h>randomPoint(&pSearch, pMin, pMax); //随机生成搜索点PointXYZ tmp; //用于存储临时点int K = 2;std::vector<int> ptIdxByKNN(K); //存储查询点近邻索引std::vector<float> ptKNN(K); //存储近邻点对应距离平方kdtree.nearestKSearch(pSearch, K, ptIdxByKNN, ptKNN); //执行K近邻搜索cout << "KNN search with K=" << K << endl; for (size_t i = 0; i < ptIdxByKNN.size(); ++i) {tmp = cloud->points[ptIdxByKNN[i]];cout << tmp.x << " " << tmp.y << " " << tmp.z //打印搜索到的点<< " (squared distance: " << ptKNN[i] << ")" << endl;}// 半径 R内近邻搜索方法float r = 2.5;std::vector<int> ptIdxByRadius; //存储近邻索引std::vector<float> ptRadius; //存储近邻对应距离的平方kdtree.radiusSearch(pSearch, r, ptIdxByRadius, ptRadius);std::cout << "search with radius=" << r << endl;for (size_t i = 0; i < ptIdxByRadius.size(); ++i) {tmp = cloud->points[ptIdxByRadius[i]];cout << tmp.x << " " << tmp.y << " " << tmp.z<< " (squared distance: " << ptRadius[i] << ")" << endl;}
}
其输出结果为
the point (-6.793 -6.22287 -7.08207) will be searched
KNN search with K=2
-3.55957 -6.14628 -1.86421 (squared distance: 37.687)
-3.99903 -6.1438 -1.59019 (squared distance: 37.9733)
search with radius=6.15
-3.55957 -6.14628 -1.86421 (squared distance: 37.687)
PCL之kd-tree详解相关推荐
- 机器学习算法(二十五):KD树详解及KD树最近邻算法
目录 1 KD树 1.1 什么是KD树 1.2 KD树的构建 1.3 KD树的插入 1.4 KD树的删除 1.5 KD树的最近邻搜索算法 1.5.1 举例:查询点(2.1,3.1) 1.5.2 举例: ...
- BTree和B+Tree详解结构
如果是复合索引: 关键字的排序先排左侧字段,在左侧字段相同的情况下,再排序右侧字段. BTree和B+Tree详解 B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引. ...
- B-Tree 和 B+Tree详解
B-Tree 和 B+Tree详解 一.什么是B-Tree 1.B-树插入 2.B-树删除 3.总结 二.什么是B+Tree 1.B+树插入 2.B+树删除 3.总结 一.什么是B-Tree B-Tr ...
- PCL:k-d tree 1 讲解
1.简介 kd-tree简称k维树,是一种空间划分的数据结构.常被用于高维空间中的搜索,比如范围搜索和最近邻搜索.kd-tree是二进制空间划分树的一种特殊情况.(在激光雷达SLAM中,一般使用的是三 ...
- 数据库优化/Linux安装Mysql/B+Tree详解
一.Linux安装MySQL yum安装 #下载安装源 wget http://repo.mysql.com/mysql57-community-release-el6-8.noarch.rpm #安 ...
- PCL :K-d tree 2 结构理解
K-d tree 基础思路:(先看之前的KNN思想,更容易理解) 导语:kd 树是一种二叉树数据结构,可以用来进行高效的 kNN 计算.kd 树算法偏于复杂,本篇将先介绍以二叉树的形式来记录和索引空间 ...
- KD树详解及KD树最近邻算法
参考:http://blog.csdn.net/app_12062011/article/details/51986805 http://www.cnblogs.com/snake-hand/arch ...
- 二叉查找树(binary search tree)详解
二叉查找树(Binary Search Tree),也称二叉排序树(binary sorted tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于 ...
- 【转】.NET Core 可移植类库PCL Portable Class Library详解
转自:https://www.kaifaxueyuan.com/server/dotnet-core/dotnet-core-portable-class-library.html 在这一章中,我们将 ...
- 关于索引的B tree B-tree B+tree B*tree 详解结构图
2019独角兽企业重金招聘Python工程师标准>>> B树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结 ...
最新文章
- 使用最小堆优化Dijkstra算法
- php上传图文教程,PHP 上传图片、文件的方法
- fiddler使用AutoResponder更改请求的返回结果
- 如何将分表汇总到总表_轻松实现多表汇总数据(多表汇总成单表)
- jwt token长度限制_ASP.NET Core Web Api之JWT(一)
- python字典添加列表_【Python】对字典列表进行去重追加
- JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?
- 7 种 JavaScript 技巧使你更聪明
- java学习(117):list迭代器和包含方法
- Docker初级选手(一)
- netty sync方法_netty是如何封装NIO的
- 从入门到入土:Python爬虫学习|实例练手|爬取百度翻译|Selenium出击|绕过反爬机制|
- python手写一个迭代器_搞清楚 Python 的迭代器、可迭代对象、生成器
- WPF:window设置单一开启
- 【hihocoder 1554】最短的 Nore0061
- pdffactory 打印字体_PdfFactory Pro(PDF虚拟打印软件) 中文版分享
- Mac电脑网页完整的长截图怎么截
- 梦幻西游默认服务器怎么修改器,梦幻西游古龙服务端安装教程
- 微信/QQ/TIM消息防撤回最新补丁
- CodeForces55A - Flea travel 解题报告