一、Kdtree
KD-Tree原理详解 - 知乎
kd tree是一种变形二叉搜索树,在pcl点云中是很重要的数据结构,在对点云做滤波,三维重建等都是很重要的过程,一棵树创建的好不好都会影响到我们的搜索速度和搜索准度。
kdtree是k维度的二叉树,其中每个节点都是K维的数据,(2,2,1)表示的就是3维的,(2,1)表示的就是2维度的,那么我们看一下kdtree 的数据结构是什么样的:
kdtree 的数据结构
struct kdtree
{
Node_data; // 某个节点的点云数据,K=3,(x,y,z), k=6 (x,y,z,r,g,b), 是一个数据矢量
range; // 表示的是这个节点所代表的空间范围 是一个空间矢量
split; // 垂直与分割超平面的方向和轴序号 是一个整数
left // 由位于该节点分割超平面左子树空间内所有数据点构成的kd-tree
right // 由位于该节点分割超平面右子树空间内所有数据点构成的kd-tree
parent; //该节点的父节点
};
如何来构建一个kdtree :
构建kdtree 是将一个无须的点云排序的过程
{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}是点云的数据。
步骤如下:
1、初始化分割轴
对每个维度的数据进行方差的计算,取得最大方差维度作为分割轴
因此我们选择x轴作为
2、确定当前的点
对1中我们选择的轴的的维度进行排序,拿到中值2,5,9,4,8,7 的中值是5,7.这种我们可以随便先一个做为当前的点,此处我们就拿(7,2)做为当前的点。
3、划分左右分支
左:(2,3)(5,4)(4.7)
右:(9,6)(8,1)
4、更新分割轴:
将剩下的轴进行方差计算,求出最大的那个方差作为分割轴,这里我们是2维的,所以只能是y轴
5、确定子节点
对步骤4中更新的轴数据进行排序,找出中位数作为当前点,这里我们找到的左节点是(5,4),右边节点是(9.6)
6、再次更新轴
从上面的案例上可以看出我们已经更新到了第三层,我们再次用x 轴作为分割轴确定当前节点为(5,4),那么左节点就是(2,3),
右节点就是(4,7)
同理我们可以确定(9.6)为当前节点,然后在进行左节点计算:(8,1)
根据重复上述的步骤,我们便可以建立一kdtree.
二维超平面(线)分割:
我们再举一个三维的案例:
(3, 1,4)
(2, 1, 3)
(2, 3, 7)
(1, 4, 4)
(2, 4, 5)
(0, 5, 7)
(6, 1, 4)
(4,0,6)
(4,3,4)
(5,2,5)
(7, 1,6)
假如这都是点云上的点,我们为了显示,分轴就按照(x,y,z)的顺序来,
1 首先按x 轴分,中位数是3 ,那么当前点就是(3,1,4)
左子树就是:
(2, 1, 3)
(2, 3, 7)
(1, 4, 4)
(2, 4, 5)
(0, 5, 7)
右子树就是:
(4,0,6)
(4,3,4)
(5,2,5)
(7, 1,6)
2、用y轴分,Left 的当前节点就是()3