k-NN:
红色是要查的点,绿色是要在周围查3个最邻近的点1,2,3。
怎么样找到一个邻域,在求法向量、上采样、下采样、噪声去除等等的问题中很重要,还有聚类、深度学习、特征提取等。有现成的库可以用,flann、PCL等,但是速度慢一些,自己写得更快。
为什么最邻近问题困难?不规则,不像图像上下左右走一圈就行;点云高一维,数据更多。建网格的话,分辨率上去,但是储存需要内存大,大部分区域空白,不高效。数据量大,110000个点/20Hz.所以需要kd树,八叉树处理海量数据。
有些区间不需要查找,怎么跳过?
怎么可以更快地搜索?
二叉树:
左边的树要比中间节点小,右边的key要比中间的root大。小放左,大放右。
1960年发明。
每个圆圈都是个节点,有个key,还有value等值也可以存储。
复杂度多少?不好说,要看二叉树建的好不好。
有可能变成一个链条。一无是处。O(h)
查找可以用递归或循环。
堆栈:stack,递归用stack
循环可以替代递归,用循环代替stack
循环可以用在GPU上。GPU上内存不够用,速度慢。
遍历,中序,前序,后序。
中序:顺序排列。
前序:复制一个树
后序:删除一个节点
1最邻近 1NN
寻找数字11
核心:8的左侧都不用寻找了,8的左侧都可以跳过。
kNN,k个最邻近点
worst distance以外的点可以被跳过
容器中保存k个距离,按顺序排列
最后一个代表需要找的点离我的最坏距离。
先确定容器:
add_point 确保了从小到大排列,方便查询最坏距离。
knn搜索算法:
先对比根节点自己,把这个点放到容器中,如果是要找的k个元素之一,就按顺序排进去,如果不在容器里,就说明比最后一个还大,加不进去;
接下来判断是去根节点的左边还是右边查找,如果比根节点大,就去根节点的右边查找,可以更快缩小最坏距离。
对于Radius NN,最坏距离已经给定,就是要查找的半径,
RadiusNN算法也可以简单些,不需要排序了。
有100个数字,找5个最邻近的点,或者半径为2.0内的点。
1维的二叉树不适用高维数据。
这是branch-n-Bound算法的分支。