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. 选择分割维度从数据集中选择一个维度进行分割。通常选择当前维度上的方差最大的维度,以最大化分割的效果。这可以帮助平衡树的结构。
  2. 选择分割点:在选择的分割维度上选择中位数作为分割点。中位数确保每次分割后,两个子空间包含的点数大致相等,从而保持树的平衡。
  3. 递归构建子树:对于每个子集,递归地选择新的分割维度和分割点,直到达到某个终止条件,例如节点包含的点数小于某个阈值或树的深度达到预定值。

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])

四、实现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/42187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ai native 模型微调

AI native 模型微调(fine-tuning)是指在预训练模型的基础上,通过对其参数进行进一步训练,使其在特定任务上表现更佳。以下是关于模型微调的一些基本步骤和概念: ### 1. 准备数据集 - **数据收集**:收集适用…

后端之路——登录校验前言(Cookie\ Session\ JWT令牌)

前言:Servlet 【登录校验】这个功能技术的基础是【会话技术】,那么在讲【会话技术】的时候必然要谈到【Cookie】和【Session】这两个东西,那么在这之前必须要先讲一下一个很重要但是很多人都会忽略的一个知识点:【Servlet】 什么是…

Oracle PL/SQL 循环批量执行存储过程

1. 查询存储过程 根据数据字典USER_OBJECTS查询出所有存储过程。 2. 动态拼接字符串(参数等) 根据数据字典USER_ARGUMENTS动态拼接参数。 3. 动态执行 利用EXECUTE IMMEDIATE动态执行无名块。 4. 输出执行信息 利用DBMS_OUTPUT.PUT_LINE输出执行成功与…

Android Gradle 开发与应用 (十): Gradle 脚本最佳实践

目录 1. 使用Gradle Kotlin DSL 1.1 什么是Gradle Kotlin DSL 1.2 迁移到Kotlin DSL 1.3 优势分析 2. 优化依赖管理 2.1 使用依赖版本管理文件 2.2 使用依赖分组 3. 合理使用Gradle插件 3.1 官方插件和自定义插件 3.2 插件管理的最佳实践 4. 任务配置优化 4.1 使用…

Oracle 19c 统一审计表清理

zabbix 收到SYSAUX表空间告警超过90%告警,最后面给出的清理方法只适合ORACLE 统一审计表的清理,传统审计表的清理SYS.AUD$不适合,请注意。 SQL> Col tablespace_name for a30 Col used_pct for a10 Set line 120 pages 120 select total.…

STM32实战篇:闪灯 × 流水灯 × 蜂鸣器

IO引脚初始化 即开展某项活动之前所做的准备工作,对于一个IO引脚来说,在使用它之前必须要做一些参数配置(例如:选择工作模式、速率)的工作(即IO引脚的初始化)。 IO引脚初始化流程 1、使能IO引…

LED灯的呼吸功能

"呼吸功能"通常是指 LED 灯的一种工作模式,它模拟人类的呼吸节奏,即 LED 灯的亮度会周期性地逐渐增强然后逐渐减弱,给人一种 LED 在"呼吸"的感觉。这种效果通常用于指示设备的状态或者简单地作为装饰效果。(就…

Spring Boot Security自定义AuthenticationProvider

以下是一个简单的示例,展示如何使用AuthenticationProvider自定义身份验证。首先,创建一个继承自标准AuthenticationProvider的类,并实现authenticate方法。 import com.kamier.security.web.service.MyUser; import org.springframework.se…

【Adobe】Photoshop图层的使用

Adobe Photoshop(简称PS)中的图层是图像处理中一个核心概念,它允许用户以堆叠的方式组织图像的不同部分,从而实现对图像的复杂编辑和处理而不影响原始图像。以下是关于Adobe Photoshop图层的详细介绍: 一、图层的定义 图层就像是透明的纸张,你可以在上面绘制、添加图像…

YOLOv10改进 | EIoU、SIoU、WIoU、DIoU、FocusIoU等二十余种损失函数

一、本文介绍 这篇文章介绍了YOLOv10的重大改进,特别是在损失函数方面的创新。它不仅包括了多种IoU损失函数的改进和变体,如SIoU、WIoU、GIoU、DIoU、EIOU、CIoU,还融合了“Focus”思想,创造了一系列新的损失函数。这些组合形式的…

Android Init Language自学笔记

Android Init Language由五个元素组成:Acttions、Commands、Services、Options和Imports。 Actions和Services隐式声明了一个新的section。所以的Commands和Options都属于最近声明的section。 Services具有唯一的名称,如果重名会报错。 Actions Acti…

解决Spring Boot中的高可用性设计

解决Spring Boot中的高可用性设计 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 高可用性设计概述 1.1 什么是高可用性? 高可用性指系统在面对各种故障和异常情况时,仍…

独立开发者系列(22)——API调试工具apifox的使用

接口的逻辑已经实现,需要对外发布接口,而发布接口的时候,我们需要能自己简单调试接口。当然,其实自己也可以写简单的代码调试自己的接口,因为其实就是简单的request请求或者curl库读取,调整请求方式get或者…

如果MySQL出现 “Too many connections“ 错误,该如何解决?

当你想要连接MySQL时出现"Too many connections" 报错的情况下,该如何解决才能如愿以偿呢?都是哥们儿,就教你两招吧! 1.不想重启数据库的情况下 你可以尝试采取以下方法来解决: 增加连接数限制&#xff1a…

RxJava学习记录

文章目录 1. 总览1.1 基本原理1.2 导入包和依赖 2. 操作符2.1 创建操作符2.2 转换操作符2.3 组合操作符2.4 功能操作符 1. 总览 1.1 基本原理 参考文献 构建流:每一步操作都会生成一个新的Observable节点(没错,包括ObserveOn和SubscribeOn线程变换操作…

asp.netWebForm(.netFramework) CSRF漏洞

asp.netWebForm(.netFramework) CSRF漏洞 CSRF(Cross-Site Request Forgery)跨站请求伪造是一种常见的 Web 应用程序安全漏 洞,攻击者通过诱使已认证用户在受信任的网站上执行恶意操作,从而利用用户的身份 执行未经授权的操作。攻…

echarts实现3D饼图

先看下最终效果 实现思路 使用echarts-gl的曲面图&#xff08;surface&#xff09;类型 通过parametric绘制曲面参数实现3D效果 代码实现 <template><div id"surfacePie"></div> </template> <script setup>import {onMounted} fro…

简单的找到自己需要的flutter ui 模板

简单的找到自己需要的flutter ui 模板 网站 https://flutterawesome.com/ 简介 我原本以为会很难用 实际上不错 很简单 打开后界面类似于,右上角可以搜索 点击view github 相当简单 很oks

RabbitMq,通过prefetchCount限制消费并发数

1.问题:项目瓶颈,通过rabbitMq来异步上传图片,由于并发上传的图片过多导致阿里OSS异常, 解决方法:通过prefetchCount限制图片上传OSS的并发数量 2.定义消费者 Component AllArgsConstructor Slf4j public class ReceiveFaceImageEvent {private final UPloadService uploadSe…

【见刊通知】MVIPIT 2023机器视觉、图像处理与影像技术国际会议

MVIPIT 2023&#xff1a;https://ieeexplore.ieee.org/xpl/conhome/10578343/proceeding 入库Ei数据库需等20-50天左右 第二届会议征稿启动&#xff08;MVIPIT 2024&#xff09; The 2nd International Conference on Machine Vision, Image Processing & Imaging Techn…