# 该文件(result_set)定义了在树中查找数据所需要的数据结构,类似一个中间件import copyclass DistIndex:def __init__(self, distance, index):#初始化类DistIndexself.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
# kdtree的具体实现,包括构建和查找import random
import math
import numpy as npfrom result_set import KNNResultSet, RadiusNNResultSet# Node类,Node是tree的基本组成元素
class Node:def __init__(self, axis, value, left, right, point_indices):self.axis = axisself.value = valueself.left = leftself.right = rightself.point_indices = point_indicesdef is_leaf(self):if self.value is None:return Trueelse:return Falsedef __str__(self):output = ''output += 'axis %d, ' % self.axisif self.value is None:output += 'split value: leaf, 'else:output += 'split value: %.2f, ' % self.valueoutput += 'point_indices: 'output += str(self.point_indices.tolist())return output# 功能:构建树之前需要对value进行排序,同时对一个的key的顺序也要跟着改变
# 输入:
#     key:键
#     value:值
# 输出:
#     key_sorted:排序后的键
#     value_sorted:排序后的值
def sort_key_by_vale(key, value):assert key.shape == value.shapeassert len(key.shape) == 1sorted_idx = np.argsort(value)key_sorted = key[sorted_idx]value_sorted = value[sorted_idx]return key_sorted, value_sorteddef axis_round_robin(axis, dim):if axis == dim-1:return 0else:return axis + 1# 功能:通过递归的方式构建树
# 输入:
#     root: 树的根节点
#     db: 点云数据
#     point_indices:排序后的键
#     axis: scalar
#     leaf_size: scalar
# 输出:
#     root: 即构建完成的树
def kdtree_recursive_build(root, db, point_indices, axis, leaf_size):if root is None:root = Node(axis, None, None, None, point_indices)# determine whether to split into left and rightif len(point_indices) > leaf_size:# --- get the split position ---point_indices_sorted, _ = sort_key_by_vale(point_indices, db[point_indices, axis])  # M# 作业1# 屏蔽开始middle_left_idx=math.ceil(point_indices_sorted.shape[0]/2)-1#math.ceil(x)返回大于等于x的最小整数middle_left_point_idx=point_indices_sorted[middle_left_idx]middle_left_point_value=db[middle_left_point_idx,axis]middle_right_idx=middle_left_idx+1#math.ceil(x)返回大于等于x的最小整数middle_right_point_idx=point_indices_sorted[middle_right_idx]middle_right_point_value=db[middle_right_point_idx,axis]root.value=(middle_left_point_value+middle_right_point_value)*0.5root.left=kdtree_recursive_build(root.left,db,point_indices_sorted[0:middle_right_idx],axis_round_robin(axis,dim=db.shape[1]),left_size)root.right=kdtree_recursive_build(root.right,db,point_indices_sorted[middle_right_idx:],axis_round_robin(axis,dim=db.shape[1]),left_size)# 屏蔽结束return root# 功能:翻转一个kd树
# 输入:
#     root:kd树
#     depth: 当前深度
#     max_depth:最大深度
def traverse_kdtree(root: Node, depth, max_depth):depth[0] += 1if max_depth[0] < depth[0]:max_depth[0] = depth[0]if root.is_leaf():print(root)else:traverse_kdtree(root.left, depth, max_depth)traverse_kdtree(root.right, depth, max_depth)depth[0] -= 1# 功能:构建kd树(利用kdtree_recursive_build功能函数实现的对外接口)
# 输入:
#     db_np:原始数据
#     leaf_size:scale
# 输出:
#     root:构建完成的kd树
def kdtree_construction(db_np, leaf_size):N, dim = db_np.shape[0], db_np.shape[1]# build kd_tree recursivelyroot = Noneroot = kdtree_recursive_build(root,db_np,np.arange(N),axis=0,leaf_size=leaf_size)return root# 功能:通过kd树实现knn搜索,即找出最近的k个近邻
# 输入:
#     root: kd树
#     db: 原始数据
#     result_set:搜索结果
#     query:索引信息
# 输出:
#     搜索失败则返回False
def kdtree_knn_search(root: Node, db: np.ndarray, result_set: KNNResultSet, query: np.ndarray):if root is None:return Falseif root.is_leaf():# compare the contents of a leafleaf_points = db[root.point_indices, :]diff = np.linalg.norm(np.expand_dims(query, 0) - leaf_points, axis=1)for i in range(diff.shape[0]):result_set.add_point(diff[i], root.point_indices[i])return False# 作业2# 提示:仍通过递归的方式实现搜索# 屏蔽开始if query[root.axis]<=root.value:kdtree_knn_search(root.left,db,result_set,query)if math.fabs(query[root.axis]-root.value)<result_set.worstDist():kdtree_knn_search(root.right,db,result_set,query)else:kdtree_knn_search(root.right,db,result_set,query)if math.fabs(query[root.axis]-root.value)<result_set.worstDist():knn_search(root.left,db,result_set,query)# 屏蔽结束return False# 功能:通过kd树实现radius搜索,即找出距离radius以内的近邻
# 输入:
#     root: kd树
#     db: 原始数据
#     result_set:搜索结果
#     query:索引信息
# 输出:
#     搜索失败则返回False
def kdtree_radius_search(root: Node, db: np.ndarray, result_set: RadiusNNResultSet, query: np.ndarray):if root is None:return Falseif root.is_leaf():# compare the contents of a leafleaf_points = db[root.point_indices, :]diff = np.linalg.norm(np.expand_dims(query, 0) - leaf_points, axis=1)for i in range(diff.shape[0]):result_set.add_point(diff[i], root.point_indices[i])return False# 作业3# 提示:通过递归的方式实现搜索# 屏蔽开始if query[rooot.axis]<=root.value:kdtree_radius_search(root.left,db,result_set,query)if math.fabs(query[root.axis]-root.value)<result_set.worstDist():kdtree_radius_search(root.right,db,result_set,query)else:kdtree_radius_search(root.right,db,result_set,query)if math.fabs(query[root.axis]-root.value)<result_set.worstDist():kdtree_radius_search(root.left,db,result_set,query)# 屏蔽结束return Falsedef main():# configurationdb_size = 64dim = 3leaf_size = 4k = 1db_np = np.random.rand(db_size, dim)root = kdtree_construction(db_np, leaf_size=leaf_size)depth = [0]max_depth = [0]traverse_kdtree(root, depth, max_depth)print("tree max depth: %d" % max_depth[0])# query = np.asarray([0, 0, 0])# result_set = KNNResultSet(capacity=k)# knn_search(root, db_np, result_set, query)## print(result_set)## diff = np.linalg.norm(np.expand_dims(query, 0) - db_np, axis=1)# nn_idx = np.argsort(diff)# nn_dist = diff[nn_idx]# print(nn_idx[0:k])# print(nn_dist[0:k])### print("Radius search:")# query = np.asarray([0, 0, 0])# result_set = RadiusNNResultSet(radius = 0.5)# radius_search(root, db_np, result_set, query)# print(result_set)if __name__ == '__main__':main()

点云课程学习——点云结构与查找(一)相关推荐

  1. 阿里云ACA认证课程学习(阿里云简介掌握云服务器ECS)

    阿里云ACA认证课程学习 阿里云高校计划 https://developer.aliyun.com/adc/college/ 阿里云简介 阿里云 成立于2009年9月10日 在杭州.北京和硅谷设有研发 ...

  2. 计算机网络学习云平台,云计算机网络学习系统,云计算机网络实验室设备

    原标题:云计算机网络学习系统,云计算机网络实验室设备 KH-E1云计算机网络实验室设备 一.概述 E1系列云计算千兆数字多媒体实时可视化网络交互式教学平台,在计算机工作模式,无PC.无220V强电的状 ...

  3. 云服务器学习linux_云服务器怎么选linux系统

    我们知道,Linux服务器系统有很多的发行版,包含Ubuntu.Debian.CentOS等体系,这些都是Linux非常出色的开源系统,功能大相径庭,页面和操作步骤略有不同. 下面我们来简单分析下这三 ...

  4. 【阿里云课程】图像翻译GAN结构与应用

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第11课中的一节,介绍如下: 图像翻译GAN结构与应用 本次课程是阿里天池联合有三AI推出的深度学习系列课程第11期,深度生 ...

  5. 【阿里云课程】深度学习模型设计:卷积核的设计与优化

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第10课中的一节,介绍如下: 卷积核与卷积方式的设计 本次课程是阿里天池联合有三AI推出的深度学习系列课程第10期,深度学习 ...

  6. 【阿里云课程】分组网络原理,结构发展及设计改进

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第10课中的一节,介绍如下: 分组网络原理与结构演变 本次课程是阿里天池联合有三AI推出的深度学习系列课程第10期,深度学习 ...

  7. 【阿里云课程】残差网络原理,结构发展及有效性理解

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第10课中的一节,介绍如下: 残差网络原理与结构演变 本次课程是阿里天池联合有三AI推出的深度学习系列课程第10期,深度学习 ...

  8. 【阿里云课程】详解深度学习优化:参数初始化,激活函数,标准化,池化

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第6课中两节,介绍如下: 第1节:激活函数与参数初始化 第1节课内容为:卷积神经网络的上篇,简单介绍卷积神经网络的生物学机制 ...

  9. 【阿里云课程】详解深度学习优化:泛化与正则化,学习率与最优化

    大家好,继续更新有三AI与阿里天池联合推出的深度学习系列课程,本次更新内容为第6课中两节,介绍如下: 第1节:泛化与正则化 第1节课内容为:泛化与正则化,讲述泛化的概念与重要性,各种正则化方法,包括显 ...

  10. 阿里云官方学习课程推荐-Linux运维学习路线 从事云计算运维相关工作必备技能

    阿里云官方学习课程推荐-Linux运维学习路线 从事云计算运维相关工作必备技能 目前越来越多的企业需要依赖于IT技术发布产品与服务,尤其是电子商务最为明显,它凸显了IT技术在现代企业中的重要性.当企业 ...

最新文章

  1. Kaggle-MNIST之路
  2. BZOJ1856:[SCOI2010]字符串
  3. [Buzz.Today]2011.06.26
  4. sun.misc.Unsafe苦难告诉我们什么
  5. 阿里云佘俊泉:创新探索不停,边缘云持续为客户创造价值
  6. 计算机编程竞赛怎么入门,acm编程比赛入门题目集..pdf
  7. css html 双面打印_CSS语法与规则 — 重学CSS
  8. c语言字符马图案,C语言实现马踏棋盘
  9. 力扣——在排序数组中查找元素的第一个和最后一个位置
  10. Julia和Matlab中的sum()的不同
  11. android 断点下载的实现,自己动手实现一个Android断点下载
  12. mysql统计分组求和
  13. OpenCC的编译与多语言使用
  14. IO流案例:字符串反转
  15. 使用BeautifulSoup,解释器报错‘lxml‘
  16. 忍得住清贫 耐得住寂寞 禁得起诱惑
  17. 图6——深度遍历无向图
  18. 智慧园区地图导航解决方案,如何实现园区内地图导航?
  19. HTTP请求一张图片,转为流返回
  20. 常用电平标准——LVTTL、LVCMOS、LVDS等

热门文章

  1. input 框隐藏光标问题
  2. 商鼎云PC端正式亮相—开启内测通告
  3. C盘哪些文件可以删除?windows7瘦身攻略
  4. ERROR 999999: Error executing function. The table name is invalid. Failed to execute (Reclassify).
  5. 计算机软件师社会需求,java软件工程师的社会环境如何?
  6. 使用gsds绘制基因结构图_使用 GSDS 绘制基因结构图
  7. 企业网站建设需要从哪些方面入手
  8. 服务器系统内存不能为written,LOL选了英雄之后出现 无法连接服务器, 0x007197ea指令引用的0x0000003c内存。该内存不能为written。高悬赏...
  9. 一元线性拟合的matlab,基于MATLAB的一元线性回归分析
  10. UltraCompare Crack,重复文件查找器