三维点云学习(2)上

二叉树实现K-NN Radius-NN Search

代码来自 黎老师github

个人心得

二叉树的搜寻方法

正如老师课堂所说,实现二叉树的搜寻有两种方法,一种是递归,一种是循环判断,本质区别并不大

#递归搜寻
def searchrecursively(root,key):               #1NN 搜索 ,递归法if root is None or root.key == key:return rootif key < root.key:return searchrecursively(root.left,key)elif key > root.key:return searchrecursively(root.right,key)#循环判断搜寻
def searchiterative(root, key):                #1NN 搜索 ,循环判断currentnode = root while currentnode is not None: if currentnode.key == key: return currentnode elif key < currentnode.key: currentnode = currentnode.left elif key > currentnode.key: currentnode = currentnode.right return currentnode

二叉树的优势,减少搜寻的复杂度

实际运行结果

Search in 100 points, takes 7 comparison only #使用二叉树仅仅比较7次
Complexity is around O(log2(n)), n is number of
database points, if tree is balanced #假设二叉树是平衡的,复杂度为log2(n),n为二叉树的深度
Worst O(N) #最坏结果,比较100次

kNN Search:
index - distance
24 - 0.00
85 - 1.00
42 - 1.00
12 - 2.00
86 - 2.00
In total 8 comparison operations.
Radius NN Search:
index - distance
24 - 0.00
85 - 1.00
42 - 1.00
12 - 2.00
86 - 2.00
In total 5 neighbors within 2.000000.
There are 8 comparison operations.

二叉树的三种应用

#二叉树的三种应用
def inorder(root):# Inorder (Left, Root, Right)if root is not None:inorder(root.left)print(root)inorder(root.right)def preorder(root):# Preorder (Root, Left, Right)if root is not None:print(root)preorder(root.left)preorder(root.right)def postorder(root):# Postorder (Left, Right, Root)if root is not None:postorder(root.left)postorder(root.right)print(root)

1NN搜寻过程

KNN search

worst Distance for KNN


具体思路:
1.先创建一个能容纳需要的临近点结果的list
2.将暂时的KNN result 进行sorted
3.最大worst
dist 的点在KNN result list的最后(随时被替代)
4.根据worstlist的不断更新,动态修改KNN result里的结果

Radius NN search

方法思路和KNN算法差不多,区别在于
Worst distance is fixed.(Radius NN search预先设定检测radius,在radius里进行点的筛选)

KNN search VS Radius NN search

完整代码

lidar_KnnRnnMain_2.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 20 10:23:37 2021@author: renzhanqi
"""import random
import math
import  numpy as npfrom lidar_KnnRnnClass_2 import  KNNResultSet,RadiusNNResultSetclass Node:                          #节点,每一个数都是一个分支节点def __init__(self,key,value=-1):self.left = Noneself.right = Noneself.key =keyself.value = value      #value可以用作储存其他数值,譬如点原来的序号def __str__(self):return "key: %s, value: %s" % (str(self.key), str(self.value))def insert(root,key,value=-1):    #构建二叉树if root is None:root = Node(key,value)      #赋初值else:if key < root.key:root.left = insert(root.left,key,value)   #小数放左边elif key > root.key:root.right = insert(root.right,key,value)  #大数放右边else:   # don't insert if key already exist in the treepassreturn  root#二叉树的三种应用
def inorder(root):# Inorder (Left, Root, Right)if root is not None:inorder(root.left)print(root)inorder(root.right)def preorder(root):# Preorder (Root, Left, Right)if root is not None:print(root)preorder(root.left)preorder(root.right)def postorder(root):# Postorder (Left, Right, Root)if root is not None:postorder(root.left)postorder(root.right)print(root)def knn_search(root:Node,result_set:KNNResultSet,key):if root is None:return False# compare the root itselfresult_set.add_point(math.fabs(root.key - key),root.value)       #计算worst_dist ,并把当前root.value(index二叉树)里的值加入到resut_set 中if result_set.worstDist() == 0:return Trueif root.key >= key:# iterate left branch firstif knn_search(root.left, result_set, key):return Trueelif math.fabs(root.key-key) < result_set.worstDist():return knn_search(root.right, result_set, key)return Falseelse:# iterate right branch firstif knn_search(root.right, result_set, key):return Trueelif math.fabs(root.key-key) < result_set.worstDist():return knn_search(root.left, result_set, key)return Falsedef radius_search(root: Node, result_set: RadiusNNResultSet, key):if root is None:return False# compare the root itselfresult_set.add_point(math.fabs(root.key - key), root.value)if root.key >= key:# iterate left branch firstif radius_search(root.left, result_set, key):return Trueelif math.fabs(root.key-key) < result_set.worstDist():return radius_search(root.right, result_set, key)return Falseelse:# iterate right branch firstif radius_search(root.right, result_set, key):return Trueelif math.fabs(root.key-key) < result_set.worstDist():return radius_search(root.left, result_set, key)return Falsedef search_recursively(root,key):               #1NN 搜索 ,递归法if root is None or root.key == key:return rootif key < root.key:return search_recursively(root.left,key)elif key > root.key:return search_recursively(root.right,key)def search_iterative(root, key):                #1NN 搜索 ,循环判断current_node = rootwhile current_node is not None:if current_node.key == key:return current_nodeelif key < current_node.key:current_node = current_node.leftelif key > current_node.key:current_node = current_node.rightreturn current_nodedef main():# Data generationdb_size = 100k = 5    #搜寻5个点radius = 2.0data = np.random.permutation(db_size).tolist()   #random.permutation 随机排列一个数组root =Nonefor i,point in enumerate(data):root = insert(root,point,i)query_key = 6result_set = KNNResultSet(capacity=k)knn_search(root, result_set, query_key)print('kNN Search:')print('index - distance')print(result_set)result_set = RadiusNNResultSet(radius=radius)radius_search(root, result_set, query_key)print('Radius NN Search:')print('index - distance')print(result_set)# print("inorder")# inorder(root)# print("preorder")# preorder(root)# print("postorder")# postorder(root)# node = search_recursive(root, 2)# print(node)## node = search_iterative(root, 2)# print(node)if __name__ == '__main__':main()

lidar_KnnRnnClass_2.py(KNN Radius NN search config fcn)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 20 10:22:24 2021@author: renzhanqi
"""import copyclass DistIndex:def __init__(self, distance, index):self.distance = distanceself.index = indexdef __lt__(self, other):return self.distance < other.distanceclass KNNResultSet:def __init__(self, capacity):self.capacity = capacityself.count = 0self.worst_dist = 1e10self.dist_index_list = []for i in range(capacity):self.dist_index_list.append(DistIndex(self.worst_dist, 0))self.comparison_counter = 0def size(self):return self.countdef full(self):return self.count == self.capacitydef worstDist(self):return self.worst_distdef add_point(self, dist, index):self.comparison_counter += 1if dist > self.worst_dist:returnif self.count < self.capacity:self.count += 1i = self.count - 1while i > 0:if self.dist_index_list[i - 1].distance > dist:self.dist_index_list[i] = copy.deepcopy(self.dist_index_list[i - 1])i -= 1else:breakself.dist_index_list[i].distance = distself.dist_index_list[i].index = indexself.worst_dist = self.dist_index_list[self.capacity - 1].distancedef __str__(self):output = ''for i, dist_index in enumerate(self.dist_index_list):output += '%d - %.2f\n' % (dist_index.index, dist_index.distance)output += 'In total %d comparison operations.' % self.comparison_counterreturn outputclass RadiusNNResultSet:def __init__(self, radius):self.radius = radiusself.count = 0self.worst_dist = radiusself.dist_index_list = []self.comparison_counter = 0def size(self):return self.countdef worstDist(self):return self.radiusdef add_point(self, dist, index):self.comparison_counter += 1if dist > self.radius:returnself.count += 1self.dist_index_list.append(DistIndex(dist, index))def __str__(self):self.dist_index_list.sort()output = ''for i, dist_index in enumerate(self.dist_index_list):output += '%d - %.2f\n' % (dist_index.index, dist_index.distance)output += 'In total %d neighbors within %f.\nThere are %d comparison operations.' \% (self.count, self.radius, self.comparison_counter)return output

三维点云学习(2)上- 二叉树实现K-NN Radius-NN Search相关推荐

  1. 三维点云学习(1)上-PCA主成分分析 法向量估计

    三维点云学习(1)上 环境安装 1.系统环境 win10 或者 ubuntu 2. Anaconda3+python3.6 使用Anaconda创建的conda虚拟环境进行python的编写 环境安装 ...

  2. 三维点云学习(4)5-DBSCNA python 复现-2-kd-_tree加速

    三维点云学习(4)5-DBSCNA python 复现-2-kd-tree加速 因为在上一章DBSCAN在构建距离矩阵时,需要构建一个NN的距离矩阵,严重占用资源,古采用kd_tree搜索进行进一步的 ...

  3. 三维点云学习(2)中-Kd-tree (k-dimensional tree)

    三维点云学习(2)中-Kd-tree (k-dimensional tree) kd-tree 实现 代码来自黎老师github 三维kd-tree 的图示 如下图所示,为三维kd-tree的切割图, ...

  4. 三维点云学习(5)4-实现Deeplearning-PointNet-1-数据集的批量读取

    三维点云学习(5)4-实现Deeplearning-PointNet-1-数据集的批量读取 Github PointNet源码 数据集下载:为40种物体的三维点云数据集 提取码:es14 因为本人初次 ...

  5. 三维点云学习(4)4-Hough Transform

    三维点云学习(4)4-Hough Transform 霍夫变换的理论通俗理解 Hough Tansform 霍夫变换 核心思想: a.原始空间中得点->参数空间中的线 b.原始空间得线-> ...

  6. 三维点云学习(4)7-ransac 地面分割+ DBSCAN聚类比较

    三维点云学习(4)7-ransac 地面分割+ DBSCAN聚类比较 回顾: 实现ransac地面分割 DBSCNA python 复现-1- 距离矩阵法 DBSCNA python 复现-2-kd- ...

  7. 三维点云学习(4)6-ransac 地面分割

    三维点云学习(4)6-ransac 地面分割 ransac课堂笔记 git大神参考代码 ransac代码主要参考如下知乎大佬的ransac的线性拟合 ransac的线性拟合 使用ransac进行地面分 ...

  8. 三维点云学习(3)8- 实现Spectral谱聚类

    三维点云学习(3)8- 实现Spectral谱聚类 谱聚类代码参考 课堂谱聚类理论笔记 效果图 原图 效果图 前三种为自写的聚类算法,分别是 KMeans.GMM.Spectral,后面为sklear ...

  9. 三维点云学习(3)7- 实现GMM

    三维点云学习(3)7- 实现GMM github大神参考代码 高斯混合模型的通俗理解 GMM课程个人总结笔记 最终效果图 原图 进行高斯聚类后的图 代码编写流程 1.输入数据集x1 x2 -xn,和K ...

最新文章

  1. Javaweb环境配置,使用2014MyEclipse全过程详解!搭建JDK环境,Tomcat环境!破解2014MyEclipse。
  2. python excel 追加写入_python excel写入及追加写入
  3. python的concat函数_python concat函数
  4. python基础知识和运用
  5. java web 程序---购物车项目内容:
  6. eps如何建立立体白模_从几个方面说说自动化立体仓库的特别之处
  7. php获取ios,IOS 通过描述获取UDID PHP代码版
  8. 因政府禁令 微软 Windows 9 将作出重大调整
  9. tcl之quartus 脚本学习 · 1 quartus tcl packages 介绍
  10. maven下载安装配置3.5.2
  11. android redis客户端,redis client (redis客户端)
  12. 服务器的使用:Linux一键搭建KMS激活服务器
  13. vs code查找内容(当前文件查找/全局查找)
  14. “共码未来”——2022Google开发者大会纪行
  15. XenApp6.5产品BUG
  16. OpenGL之GLEW安装
  17. 自动驾驶技术之——被低估的传感器超声波雷达
  18. Smurf攻击的原理
  19. 智能金融再突破·TAI让反洗钱更快一步
  20. 基于MQTT和nodeMCU的音乐弹奏APP【100010341】

热门文章

  1. 解决:安装R包时,经常提示“package ‘readr’ is not available (for R version 3.5.1)”的问题
  2. 确定数组是否包含值[重复]
  3. html onblur 函数执行了2次,JavaScript“onblur事件”调用函数失效 原因与解决方法
  4. 分小组 java_蓝桥杯-分小组-java
  5. 2021普通高考重庆成绩查询平台,2021年重庆高考成绩查询时间及查分方式
  6. 关于现代计算机的知识,从资本经济到知识经济:现代计算机的知识革命
  7. exfat最佳单元大小_2020年Window系统重装最佳方式
  8. 指针02:指针所占内存空间
  9. L1-014 简单题 (5 分)
  10. div盒子水平垂直居中的方法