基于kdtree的三种搜索近邻点(python版本)

news2024/11/18 21:35:55

1、前言

      点云中近邻点搜索查询是一种非常常见的数据处理操作步骤,近邻点搜索方式包括k近邻搜索、近距离搜索(球体近邻搜索)、圆柱体搜索三种方式,每一种搜索方式适用的场景各不相同。其中kdtree搜索是一种有效搜索近邻点方式,其是一种在k维空间中存储点集的数据结构,它主要用于多维空间的查询,如范围查询和最近邻查询。KD树是一种特殊的二叉树,每个节点表示一个k维数据点。本博客介绍基于python语言的kdtree搜索近邻点,其中scipy库中有kdtree,可以直接近邻近邻点搜索。

3种近邻点搜索示意图

2 近邻点搜索示例

   scipy.spatial模块中的KDTree类是Python中实现KD树的一个库。它提供了高效的方法来进行多维空间的最近邻查询、范围查询等。

2.1 k近邻点搜索

      k近邻搜索是指给定待查询点,搜索距离该点最近的k个近邻点,其主要使用query函数实现k近邻查询。代码如下,对于待搜索点querypt,使用kdtree搜索距离其最近的50个近邻点,命令为nearest_dist, nearest_idx = kdtree.query(querypt,k=50)。根据索引nearest_idx得到最近的50个近邻点。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.spatial import KDTree
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号

with open('E:\\testdata01.txt', 'r') as file:
    # 初始化一个列表来存储所有的点
    points = []

    # 逐行读取数据
    for line in file:
        # 去除行尾的换行符并分割字符串
        x, y, z, L = line.strip().split()
        # 将字符串转换为浮点数
        x = float(x)
        y = float(y)
        z = float(z)
        # 将点添加到列表中
        points.append((x, y, z))

querypt=points[800]
kdtree=KDTree(points) #创建kdtree
nearest_dist, nearest_idx = kdtree.query(querypt,k=50)
nearest_points = [points[i] for i in nearest_idx]


fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(*zip(*points), marker='.', color='blue', s=20)

ax.scatter(*zip(*nearest_points), marker='*', color='red', s=20)
ax.scatter(*zip(*[querypt]), marker='o', color='red', s=30)

ax.set_title("三维点云可视化")
ax.set_xlabel("x轴")
ax.set_ylabel("y轴")
ax.set_zlabel("z轴")
plt.show()

      搜索的近邻点,已经按照从近到远进行排序,同时搜索的最近点,是该搜索点自身(如果待搜索点属于kdtree中某一点的话)。搜索近邻点结果如下,红色箭头为待搜索点,搜索的50个点位于该点附近,证明搜索的近邻点正确。

2.2 距离近邻点搜索

       近距离搜索是搜索距离该点范围内点,即所有点到该点距离均小于该范围,使用函数query_ball_point进行搜索,代码如下,kdtree使用命令nearest_idx = kdtree.query_ball_point(querypt,raduis)进行查询,但是只查询得到距离该点最近点的序号,不包括距离。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.spatial import KDTree
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号

with open('E:\\testdata01.txt', 'r') as file:
    # 初始化一个列表来存储所有的点
    points = []

    # 逐行读取数据
    for line in file:
        # 去除行尾的换行符并分割字符串
        x, y, z, L = line.strip().split()
        # 将字符串转换为浮点数
        x = float(x)
        y = float(y)
        z = float(z)
        # 将点添加到列表中
        points.append((x, y, 0))

querypt=points[800]
kdtree=KDTree(points) #创建kdtree
raduis=1.5
nearest_idx = kdtree.query_ball_point(querypt,raduis)
nearest_points = [points[i] for i in nearest_idx]


fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(*zip(*points), marker='.', color='blue', s=20)

ax.scatter(*zip(*nearest_points), marker='*', color='red', s=20)
ax.scatter(*zip(*[querypt]), marker='o', color='red', s=30)

ax.set_title("三维点云可视化")
ax.set_xlabel("x轴")
ax.set_ylabel("y轴")
ax.set_zlabel("z轴")
plt.show()

      从结果上看,待搜索点为序号为800的点,但是序号为800并没有排在最前面,说明并没有按照由远到近的顺序进行排序,是随机排序。如下图所示,为便于展示,将所有点z坐标均为0,从图可知,所有近邻点位于该点附近,同时所有近邻点近似位于一个圆内,证明距离最近点搜索正确。

2.3 圆柱体近邻点搜搜

      圆柱体近邻点搜索,即平面二维距离一定,如下图所示,忽略高程上差异。搜索这种近邻点并进行分析,可以得到该点的高程上的结构信息。

     代码如下,其中kdtree搜索时,将所有z坐标设置成0,再使用query_ball_point函数进行搜索得到近邻点,最终实现近邻点搜索。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.spatial import KDTree
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号

with open('E:\\testdata01.txt', 'r') as file:
    # 初始化一个列表来存储所有的点
    points2D = []
    points3D = []

    # 逐行读取数据
    for line in file:
        # 去除行尾的换行符并分割字符串
        x, y, z, L = line.strip().split()
        # 将字符串转换为浮点数
        x = float(x)
        y = float(y)
        z = float(z)
        # 将点添加到列表中
        points2D.append((x, y, 0))
        points3D.append((x, y, z))

id=100
querypt=points2D[id]
kdtree=KDTree(points2D) #创建kdtree
raduis=2.0
nearest_idx = kdtree.query_ball_point(querypt,raduis)
nearest_points = [points3D[i] for i in nearest_idx]


fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(*zip(*points3D), marker='.', color='blue', s=20)

querypt=points3D[id]
ax.scatter(*zip(*nearest_points), marker='*', color='red', s=20)
ax.scatter(*zip(*[querypt]), marker='o', color='red', s=30)

ax.set_title("三维点云可视化")
ax.set_xlabel("x轴")
ax.set_ylabel("y轴")
ax.set_zlabel("z轴")
plt.show()

      搜索结果如下,可以发现,对于待搜索点,搜索的圆柱体近邻点,在高程上距离其很远的点,也可以搜索得到,证明圆柱体搜索结果正确。

3、小结

      本博客介绍了基于python的kdtree的三种近邻点搜索方式,三种方式适用场景不同,可以根据实际需要来选择何种搜索方式。

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

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

相关文章

细说ARM MCU的串口接收数据的实现过程

目录 一、硬件及工程 1、硬件 2、软件目的 3、创建.ioc工程 二、 代码修改 1、串口初始化函数MX_USART2_UART_Init() (1)MX_USART2_UART_Init()串口参数初始化函数 (2)HAL_UART_MspInit()串口功能模块初始化函数 2、串口…

计划任务 之 一次性的计划任务

计划任务 作用:定时自动完成特定的工作 计划任务的分类: (1)一次性的计划任务 例如下周三对系统的重要文件备份一次 (2)周期性重复计划任务 例如每天晚上12:00备份一次 一次性的任务计划&#xff1a…

【java计算机毕设】图书管理系统javaweb java MySQL springboot vue html maven送文档+ppt 代码源码计算机项目

1项目功能 【java计算机专业学长毕业设计分享】 智慧图书管理系统 Java SpringBoot vue HTML MySQL 前后端分离 2项目介绍 系统功能: 智慧图书管理系统包括管理员和用户两种角色。 管理员的功能包括在个人中心修改个人信息和密码,管理员功能模块管理管理…

Spark学习——不同模式下执行脚本

举个简单的例子:使用spark官方用例"取pi值" 一、local模式 进入spark目录执行后台命令: bin/spark-submit \ --class org.apache.spark.examples.SparkPi \ --master local[*] \ ./examples/jars/spark-examples_2.12-3.2.1.jar \ 10运行结…

芯片级激光器研发取得新进展

欢迎关注GZH《光场视觉》 自 20 世纪 60 年代以来,激光给世界带来了革命性的变化,如今已成为从尖端手术和精密制造到光纤数据传输等现代应用中不可或缺的工具。 但是,随着激光应用需求的增长,挑战也随之而来。例如,光…

本周MoonBit新增Wasm1引用计数支持、语法即将添加错误恢复机制

MoonBit更新 【Wasm MVP】Wasm1 后端添加基于 Perceus 算法的引用计数支持 【语法】throw raise try catch 均被保留为关键字 为了即将添加的错误处理机制 【Core】List与sorted_map被移动至core/immut下 List被移动至core/immut/list包中,并被移除内置类型支持 …

重邮计算机网络803-(1)概述

目录 一.计算机网络向用户提供的最重要的功能 二.互联网概述 1.网络的网络 2.计算机网络的概念 3. 互联网发展的三个阶段 4.制订互联网的正式标准要经过以下的四个阶段 5.互联网的组成(功能) 6.互联网功能 7.互联网的组成(物理&…

为什么50etf期权涨幅这么大?

今天带你了解为什么50etf期权涨幅这么大?50ETF期权涨幅大是因为跟上证50指数,另外期权的特征自带杠杆效应在虚值合约上有特别高以小博大的效果。 为什么50etf期权涨幅这么大? 标的资产价格的大幅波动:50ETF期权的内在价值与50ETF…

坦白局考PMP真的能缓解职场焦虑吗?

我就是那个花了大几千去考了一张190个国家都认可的高含金量证书,每三年还要花150美金续证,但这个证书给我的生活带来前所未有的改变。我不知道其他人考了PMP证书如今怎么样了,我只说我自己,今天就来聊聊从我了解到拿证这一过程&am…

大规模胰腺癌检测通过非对比增强CT和深度学习| 文献速递-视觉通用模型与疾病诊断

Title 题目 Large-scale pancreatic cancer detection via non-contrast CT and deep learning 大规模胰腺癌检测通过非对比增强CT和深度学习 01 文献速递介绍 胰腺导管腺癌(PDAC)是最致命的实体恶性肿瘤,通常在晚期和不可手术的阶段被检…

HyperSnap软件最新版下载-HyperSnap官方最新版附加详细安装步骤

​HyperSnap是一个老牌优秀的屏幕截图工具,全新界面,不仅能抓取标准桌面程序,还能抓取 DirectX, 3Dfx Glide的 游戏视频或 DVD 屏幕图,能以 20 多种图形格式(包括:BMP, GIF,JPEG, TIFF, PCX等)保…

MS6001/2/4低功耗,低噪声 CMOS 轨到轨输入输出运算放大器

MS6001/2/4 运算放大器具有极低功耗,轨到轨输入输出,低 的输入电压和低的电流噪声。具体表现在可工作在幅度为 1.8V 到 5V 的单电源或者双电源条件,低功耗和低噪声使得 MS6001/2/4 能够用在可移动设备上,输入输出的轨到轨…

PyTorch 维度变换-Tensor基本操作

以如下 tensor a 为例,展示常用的维度变换操作 >>> a torch.rand(4,3,28,28) >>> a.shape torch.Size([4, 3, 28, 28])view / reshape 两者功能完全相同: a.view(shape) >>> a.view(4,3,28*28) ## a.view(4,3,28,28) 可恢复squeeze…

移动端浏览器的扫描二维码实现(vue-qrcode-reader与jsQR方式)

1. 实现功能 类似扫一扫的功能,自动识别到画面中的二维码并进行识别,也可以选择从相册中上传。 2. 涉及到的一些插件介绍 vue-qrcode-reader 一组用于检测和解码二维码的Vue.js组件 jsQR 一个纯粹的javascript二维码阅读库,该库接收原始…

基于asp.net大学生健康管理系统功能介绍

项目关键技术 开发工具:Visual Studio 编程语言: .net、JavaScript 数据库: SQL Server 框架:ASP.NET框架 关键技术:ASP.NET、SQL Server 数据库工具:Navicat 1、ASP.NET框架 ASP.NET技术框架是目前在程序开发中广泛应用的一种新…

存储协议入门-UPIU简介

写在前面:本文参考UFS jedec3.1,本文思维导图如下,详细内容关注微信:存储协议探索 ​ 1. UPIU架构 UPIU是UFS协议中的一种数据包格式,用于传输应用层的各种请求和命令,UFS采用的是客户-服务端架构,UFS主机(客户)主动发起请求,UFS设备(服务)执行后并返回相应状态。…

演出门票小程序开发

一、实时票务信息更新的重要性 在演出票务市场,票务信息的实时性对于消费者来说至关重要。一旦票务信息出现滞后或错误,不仅可能导致消费者错过心仪的演出,还可能引发一系列不必要的纠纷和投诉。因此,演出门票小程序通过引入实时…

IMU监测举重作

近日,来自加拿大的科研团队针对举重中因不当举重操作引发的普遍下背痛问题开展了一项开创性研究。团队利用穿戴式惯性测量单元(IMU)技术,在受控实验室环境中,实时监测并评估了举重动作过程中下背部肌肉与脊柱关节的受力…

The First项目报告:Stargate Finance重塑跨链金融的未来

Stargate Finance是一个基于LayerZero协议的去中心化金融平台,自2022年3月由LayerZero Labs创建以来,一直致力于为不同区块链之间的资产转移提供高效、低成本的解决方案。凭借其独特的跨链技术和丰富的DeFi服务,Stargate Finance已成为连接不…

物联网TCP、UDP、CoAP、LwM2M、MQTT协议简单对比

一、前言 目前物联网行业有TCP、UDP、CoAP、LwM2M、MQTT、Modbus系列、JT808、HTTP、TLINK、ISAPI等协议,本文先对其中的几款协议进行介绍。具体关系见下图: 传输层协议:TCP、UDP;应用层协议:CoAP、LwM2M、MQTT、Modbu…