kd-Tree主要用于大规模高维数据密集的查找比对的使用场景中,主要是最近邻查找以及近似最近邻查找。
kd-Tree属于二叉查找树BST的一种,二叉查找树:
- 若它的左子树不为空,则它的左子树节点上的值皆小于它的根节点
- 若它的右子树不为空,则它的右子树节点上的值均大于它的根节点
- 它的左右子树也分别是二叉查找树
构造BST:
- 在现有的数据中选定一个数据作为根节点的存储数值。(尽可能保证左右子树的集合的数量相等,优化查找速度)
- 将其他数据按照左小右大的规则往深层递归,直到叶节点,然后开辟新的叶节点,并存储当前值
- 新的数据按照上一条进行储存。
kd-tree的构造是在BST的基础上升级:
- 选定数据X1的Y1维数值a1作为根节点比对值,对所有的数值在Y1维进行一层BST排列。相当于根据Y1维数值a1对数据集进行分割。
- 选定数据X2的Y2维数值a2作为根节点比对值,对所有的数值在Y2维进行一层BST排列,也即将数据集在Y2维上又做一层BST
Note:
- 一般按照方差最大的维度有限进行划分;
- 为了时左右子树的节点树数相差不大(加速检索速度),选择当前维度的中值作为根节点的比对数值
代码实现
https://blog.csdn.net/silangquan/article/details/41483689
F L A N N \color{red}{FLANN} FLANN
Fast Library for Approximate Nearest Neighbors,一系列查找算法,自动选取最快算法机制,KdTree是FLANN,分两步建立索引和搜索。
步骤:
- 初始化
pcl::KdTreeFLANN<DescriptorType> match_search;
- 创建KdTreeFLANN对象,并把点云设置成输入,然后创建一个searchPoint变量(另一个点云)作为查询点
kdtree.setInputCloud(cloud);
- 创建两个变量存储搜索到的K邻近,两个向量中,一个存储搜索到查询点近邻的索引,另一个存储对应近邻的平方距离。
- 寻找输入和查询点对应最近邻的K个点(一般指描述子)
kdtree.nearestKSearch(searchPoint,K,pointIdxNKNSearch,pointNKNSquaredDistance)