Open3D KDtree的建立与使用
目录
一、概述
1.1kd树原理
1.2kd树搜索原理
1.3kd树构建示例
二、常见的领域搜索方式
2.1K近邻搜索(K-Nearest Neighbors, KNN Search)
2.2半径搜索(Radius Search)
2.3混合搜索(Hybrid Search)
三、代码实现
3.1关键函数
3.1.1K近邻搜索
3.1.2半径邻域搜索
3.1.3混合搜索
3.2完整代码
四、实现效果
一、概述
1.1kd树原理
KD树(K-Dimensional Tree)是一种用于组织k维空间数据的树状数据结构,特别适用于多维空间中的最近邻搜索和范围搜索。KD树通过递归地将空间划分为较小的子空间,从而实现高效的空间查询。
KD树的构建原理:
- 选择分割维度从数据集中选择一个维度进行分割。通常选择当前维度上的方差最大的维度,以最大化分割的效果。这可以帮助平衡树的结构。
- 选择分割点:在选择的分割维度上选择中位数作为分割点。中位数确保每次分割后,两个子空间包含的点数大致相等,从而保持树的平衡。
- 递归构建子树:对于每个子集,递归地选择新的分割维度和分割点,直到达到某个终止条件,例如节点包含的点数小于某个阈值或树的深度达到预定值。
1.2kd树搜索原理
1.最近邻搜索:
- 从根节点开始,根据查询点在当前分割维度上的值,递归地搜索子树,直到到达叶节点。
- 在回溯过程中,检查当前节点是否比已知的最近邻更近,如果是,则更新最近邻。
- 还需检查当前节点的另一子树是否可能包含更近的点,如果可能,则进行搜索。
2.范围搜索:
- 类似于最近邻搜索,通过比较查询点与分割点的关系,递归地搜索子树,检查节点是否在查询范围内。
1.3kd树构建示例
我们将使用以下点构建一个KD树:
A(2,3), B(5,4), C(9,6), D(4,7), E(8,1), F(7,2)
第一层:
- 选择 x 轴进行分割。
- 选择 x 轴上的中位数作为分割点,这里是点 D(4,7)。
D(4,7)/ \
第二层:
- 对于左子树,选择 y 轴进行分割。
- 左子树的点为 A(2,3) 和 B(5,4),选择 y 轴上的中位数点 A(2,3) 作为分割点。
- 对于右子树,选择 y 轴进行分割。
- 右子树的点为 C(9,6), E(8,1) 和 F(7,2),选择 y 轴上的中位数点 F(7,2) 作为分割点。
D(4,7)/ \A(2,3) F(7,2)\ / \B(5,4) E(8,1) C(9,6)
第三层:
- 对于左子树的右子树,选择 x 轴分割。
- 对于右子树的左右子树,选择 x 轴分割。
最终构建的KD树结构如下:
D(4,7)/ \A(2,3) F(7,2)\ / \B(5,4) E(8,1) C(9,6)
二、常见的领域搜索方式
2.1K近邻搜索(K-Nearest Neighbors, KNN Search)
K近邻搜索是找到离查询点最近的K个点的一种方法。K近邻搜索基于欧几里得距离度量,通过KD树可以高效地实现。
过程:
- 从根节点开始,根据查询点在当前分割维度上的值,递归地搜索子树,直到到达叶节点。
- 在回溯过程中,检查当前节点是否比已知的K个最近邻点更近,如果是,则更新最近邻集合。
- 还需检查当前节点的另一子树是否可能包含更近的点,如果可能,则进行搜索。
应用:
- 数据分类:KNN算法在分类问题中广泛应用,通过查找最近的K个邻居进行多数投票决定分类结果。
- 数据降噪:可以通过找到每个点的K个最近邻来平滑数据。
2.2半径搜索(Radius Search)
半径搜索是找到所有在查询点某个给定半径范围内的点的一种方法。与K近邻搜索不同,半径搜索返回的是所有在指定半径范围内的点。
过程:
- 从根节点开始,根据查询点和分割点之间的距离,递归地搜索子树。
- 检查当前节点是否在查询点的半径范围内,如果是,则将其加入结果集合。
- 检查当前节点的另一子树是否可能包含在半径范围内的点,如果可能,则进行搜索。
应用:
- 密度估计:通过找到某个区域内的所有点,可以估计该区域的点云密度。
- 空间聚类:在聚类算法中,半径搜索用于找到每个点的邻域,从而进行聚类。
2.3混合搜索(Hybrid Search)
混合搜索结合了K近邻搜索和半径搜索的特点,在进行K近邻搜索的同时,还限制了搜索范围在一个给定的半径内。也就是说,它在指定半径范围内找到最多K个最近的点。
过程:
- 从根节点开始,根据查询点在当前分割维度上的值和半径约束,递归地搜索子树,直到到达叶节点。
- 检查当前节点是否在查询点的半径范围内,并且是否属于最近的K个点,如果是,则将其加入结果集合。
- 检查当前节点的另一子树是否可能包含在半径范围内并且属于最近的K个点,如果可能,则进行搜索。
应用:
- 提高搜索效率:在处理大规模点云数据时,混合搜索可以限制搜索范围,从而提高搜索效率。
- 平衡搜索结果:混合搜索可以在保证结果精确度的同时,限制搜索范围,避免返回过多不相关的点。
三、代码实现
3.1关键函数
3.1.1K近邻搜索
search_knn_vector_3d返回查询点的k个最近邻的索引列表。这些相邻的点存储在数组numpy中,使用pcd.colors对numpy数组内所有的点进行颜色渲染(渲染为绿色[0,1,0])。这里跳过了第一个索引点,因为它是查询点本身
#K近邻搜索
pcd.colors[10000] = [1, 0, 0]#给定查询点并渲染为红色
[k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[10000], 200)#K近邻搜索
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]#K邻域的点,渲染为绿色
3.1.2半径邻域搜索
使用 search_radius_vector_3d查询所有的和查询点点距离小于给定半径的点
#半径搜索
pcd.colors[5000] = [1, 0, 0]#给定查询点并渲染为红色
[k1, idx1, _] = pcd_tree.search_radius_vector_3d(pcd.points[5000], 0.02)#半径搜索
np.asarray(pcd.colors)[idx1[1:], :] = [0, 0, 1]#半径搜索结果并渲染为蓝色
3.1.3混合搜索
除了KNN搜索(search_knn_vector_3d)和RNN搜索(search_radius_vector_3d)以外,Open3d还提供了混合搜索函数(search_hybrid_vector_3d)。它最多返回K个和查询点距离小于给定半径的最邻近点。这个函数结合了KNN和RNN的搜索条件,在某些文献中也被称作RKNN搜索。在许多情况下它有着性能优势,并且在Open3d的函数中大量的使用.
#混合搜索
pcd.colors[30000] = [1, 1, 0]#给定查询点并渲染为黄色
[k2, idx2, _] = pcd_tree.search_hybrid_vector_3d(pcd.points[30000], 0.05,200)#K近邻搜索
np.asarray(pcd.colors)[idx2[1:], :] = [0, 1, 0.8]#半径搜索结果并渲染为青色
3.2完整代码
import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("Horse.pcd")
pcd.paint_uniform_color([0.5, 0.5, 0.5])#把所有点渲染为灰色
pcd_tree = o3d.geometry.KDTreeFlann(pcd)#建立KD树索引#K近邻搜索
pcd.colors[10000] = [1, 0, 0]#给定查询点并渲染为红色[k, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[10000], 200)#K近邻搜索
np.asarray(pcd.colors)[idx[1:], :] = [0, 1, 0]#K邻域的点,渲染为绿色#半径搜索
pcd.colors[5000] = [1, 0, 0]#给定查询点并渲染为红色
[k1, idx1, _] = pcd_tree.search_radius_vector_3d(pcd.points[5000], 0.02)#半径搜索
np.asarray(pcd.colors)[idx1[1:], :] = [0, 0, 1]#半径搜索结果并渲染为蓝色#混合搜索
pcd.colors[30000] = [1, 1, 0]#给定查询点并渲染为黄色
[k2, idx2, _] = pcd_tree.search_hybrid_vector_3d(pcd.points[30000], 0.05,200)#K近邻搜索
np.asarray(pcd.colors)[idx2[1:], :] = [0, 1, 0.8]#半径搜索结果并渲染为青色
o3d.visualization.draw_geometries([pcd])
四、实现效果
相关文章:

Open3D KDtree的建立与使用
目录 一、概述 1.1kd树原理 1.2kd树搜索原理 1.3kd树构建示例 二、常见的领域搜索方式 2.1K近邻搜索(K-Nearest Neighbors, KNN Search) 2.2半径搜索(Radius Search) 2.3混合搜索(Hybrid Search) …...

C语言编程3:运算符,运算符的基本用法
C语言3🔥:运算符,运算符的基本用法 一、运算符🌿 🎇1.1 定义 运算符是指进行运算的动作,比如加法运算符"“,减法运算符”-" 算子是指参与运算的值,这个值可能是常数&a…...

如何通过SPI机制去实现读取配置文件并动态加载对应实现类
最近写完鱼皮的RPC项目后,打算整理出来一些编程技巧的模版。 有两种实现:1.ServiceLoader 2.SpiLoader 一、直接使用java.util下的ServiceLoader 首先在resource目录下创建 META-INF/services 目录,并且创一个名称为对应要实现的接口的包…...

双链表(数组模拟)
双链表(数组模拟) 什么是双链表数组模拟双链表题目 什么是双链表 双链表不同于单链表的是 每一个节点不但存储了下一个节点的位置,也存储了上一个节点的位置。 数组模拟双链表 所以如果用数组的话,就需要创建三个数组。 题目 …...
ChatGPT 5.0:一年半后的展望与看法
在人工智能领域,每一次技术的飞跃都预示着未来生活与工作方式的深刻变革。随着OpenAI在人工智能领域的不断探索与突破,ChatGPT系列模型已成为全球关注的焦点。当谈及ChatGPT 5.0在未来一年半后可能发布的前景时,我们不禁充满期待,…...

城市地下综合管廊物联网远程监控
城市地下综合管廊物联网远程监控 城市地下综合管廊,作为现代都市基础设施的重要组成部分,其物联网远程监控系统的构建是实现智慧城市建设的关键环节。这一系统集成了先进的信息技术、传感器技术、通信技术和数据处理技术,旨在对埋设于地下的…...

VS 附加进程调试
背景: 此方式适合VS、代码和待调试的exe在同一台机器上。 一、还原代码到和正在跑的exe同版本 此操作可以保证能够调试生产环境的exe 二、设置符号路径 1.调试->选项 三、附加进程 方式1: 打开VS,调试->附加到进程,出…...
核函数的深入理解
核函数 (Kernel Function)是一种在高维特征空间中隐式计算内积的方法,它允许在原始低维空间中通过一个简单的函数来实现高维空间中的内积计算,而无需显式地计算高维特征向量。 核函数 的基本思想是通过一个映射函数 ϕ \phi ϕ …...

使用Ckman部署ClickHouse集群介绍
使用Ckman部署ClickHouse集群介绍 1. Ckman简介 ClickHouse Manager是一个为ClickHouse数据库量身定制的管理工具,它是由擎创科技数据库团队主导研发的一款用来管理和监控ClickHouse集群的可视化运维工具。目前该工具已在github上开源,开源地址为&…...
「前端工具」postman接口测试工具详解
Postman 是一款流行的 API 开发工具,用于构建和测试 RESTful API。以下是 Postman 的一些关键特性和使用方法的详解: 1. 界面和基本操作 工作区:Postman 的主界面,用于显示集合、环境和全局变量。请求构建器:用于输入请求的 URL、HTTP 方法、请求头、请求体等。响应区:显…...
生成requirements.txt
pip install pipreqs pipreqs ./ --encodingutf-8 --force python导出requirements.txt的几种方法总结...
ubuntu ceph部署
ubuntu ceph部署 参考文档:http://docs.ceph.org.cn/start/ 节点配置 1个mon节点,3个osd节点 安装前准备 安装ceph-deploy 添加 release key wget -q -O- https://download.ceph.com/keys/release.asc | sudo apt-key add -添加Ceph软件包源&…...
2024.7.8
2024.7.8 【追逐影子的人,自己就是影子 —— 荷马】 Monday 六月初三 讲的根本听不懂好吧! 目前只写了三道题(但是黑色 确实是没见过这么抽象的数据结构 Gregor and the Two Painters Number of Components Equal LCM Subsets 这个lcm确实…...
Spring 外部jar包Bean自动装配
Spring 外部jar包Bean自动装配 背景介绍 公共代码模块被作为jar包引入业务项目,前者定义的bean即使添加了Component注解由于不会被扫描到也就无法被Spring管理。此处通过Spring SPI机制来完成 使用 spring.factories 在外部 jar 包中创建 spring.factories 文件&a…...

2通道音频ADC解码芯片ES7243L、ES7243E、ES7243,用于低成本实现模拟麦克风转换为IIS数字话筒
前言: 音频解码芯片某创参考价格: ES7243L 500:¥1.36 / 个 ES7243E 500:¥1.66 / 个 ES7243 500: ¥1.91 / 个 其中ES7243L工作电压为1.8V,与其他两款的3.3V工作电压不同&…...

uniapp跨域问题解决
找到menifest文件,在文件的最后添加如下代码: // h5 解决跨域问题"h5":{"devServer": {"proxy": {"/adminapi": {"target": "https://www.demo.com", // 目标访问网址"changeOrigin…...
[C++][ProtoBuf][Proto3语法][一]详细讲解
目录 1.字段规则2.消息类型的定义与使用1.定义2.使用 3.enum类型1.语法2.定义时注意3.代码 1.字段规则 消息的字段可以⽤下⾯⼏种规则来修饰: singular:消息中可以包含该字段零次或⼀次(不超过⼀次) proto3语法中,字段默认使⽤该规则 repeat…...

千古雄文《渔樵问对》原文、译文、解析
邵雍《渔樵问对》:开悟奇文,揭示世界的终极意义 【邵雍《渔樵问对》:开悟奇文,揭示世界的终极意义】 邵雍(1011年1月21日-1077年7月27日,宋真宗大中祥符四年十二月二十五日戌时生至神宗熙宁十…...
uniapp 开发备忘录-防坑指南
uniapp 开发备忘录-防坑指南 npm run dev:mp-weixin 编译微信小程序报错: [plugin:uni:mp-using-component] Expected ‘,’ or ‘}’ after property value in JSON at position 解决方案:升级uniapp 到最新 alpha 版。(2024年7月13日&am…...
Simple_ReAct_Agent
参考自https://www.deeplearning.ai/short-courses/ai-agents-in-langgraph,以下为代码的实现。 Basic ReAct Agent(manual action) import openai import re import httpx import os from dotenv import load_dotenv, find_dotenvOPENAI_API_KEY os.getenv(OPEN…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...