球形包围框-Bounding Sphere-原理-代码实现

  • 定义:通过一个球体包围所有点云点,该球体的球心和半径由点云的分布决定,并且球体的半径尽可能小。
  • 优点:计算简单,通常用于快速粗略估计物体的范围。
  • 缺点:对于不规则形状的物体,包围不紧密,容易留下较多空白区域。

下面将介绍一种常用的算法——Welzl算法,并提供Python实现的具体步骤和代码示例。

Welzl算法简介

Welzl算法是一种递归算法,用于在期望线性时间内找到一组点的最小包围球。其基本思想是随机化点的顺序,然后递归地处理每个点,决定是否需要将其包含在当前的边界集(即确定球体)的情况下更新最小包围球。

算法的核心思想是:我们逐个考虑每个点,看是否需要将它包含在球面上。如果一个点已经在当前的最小球内,我们就不需要改变球;如果不在,我们就需要重新计算球,使得这个点在新球的表面上。

实现步骤

这个实现使用了Welzl算法来计算最小包围球。以下是算法的主要步骤:

  1. welzl_algorithm 函数是算法的入口点,它调用递归函数 welzl
  2. welzl 函数是算法的核心,它递归地构建包围球:
    • 如果没有剩余点或者已经有4个点在球面上,就直接构造球。
    • 否则,它会检查当前点是否在之前构造的球内。
    • 如果不在,就将该点添加到球面点集中,并重新计算球。
  3. make_sphere 函数用于从给定的点集构造球。它计算点集的中心作为球心,最远点到中心的距离作为半径。
  4. is_point_in_sphere 函数检查一个点是否在给定的球内。
import numpy as npdef welzl_algorithm(points):def welzl(P, R, n):if n == 0 or len(R) == 4:return make_sphere(R)p = P[n-1]sphere = welzl(P, R, n-1)if sphere is None or not is_point_in_sphere(p, sphere):R.append(p)sphere = welzl(P, R, n-1)R.pop()return spherereturn welzl(points, [], len(points))def make_sphere(points):if len(points) == 0:return Noneelif len(points) == 1:return (points[0], 0)# 计算点集的中心和半径center = np.mean(points, axis=0)radius = max(np.linalg.norm(p - center) for p in points)return (center, radius)def is_point_in_sphere(point, sphere):if sphere is None:return Falsecenter, radius = spherereturn np.linalg.norm(point - center) <= radius * (1 + 1e-6)  # 添加一个小的容差# 示例使用
if __name__ == "__main__":# 生成一些随机的3D点np.random.seed(0)points = np.random.rand(20, 3) * 10# 计算包围球sphere = welzl_algorithm(points)print("包围球的中心:", sphere[0])print("包围球的半径:", sphere[1])# 验证所有点是否都在球内all_points_inside = all(is_point_in_sphere(p, sphere) for p in points)print("所有点都在球内:", all_points_inside)

利用open3d实现

这里使用的open3d中AABB方法得到圆的半径和直径,最后得到球形边界框

import open3d as o3d
import numpy as npdef compute_bounding_sphere(points):pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector(points)aabb = pcd.get_axis_aligned_bounding_box()center = aabb.get_center()radius = np.max(np.linalg.norm(points - center, axis=1))return center, radiusdef create_sphere_wireframe(center, radius, resolution=20):theta = np.linspace(0, 2*np.pi, resolution)phi = np.linspace(0, np.pi, resolution)# 创建经线meridians = []for t in theta:x = radius * np.cos(t) * np.sin(phi) + center[0]y = radius * np.sin(t) * np.sin(phi) + center[1]z = radius * np.cos(phi) + center[2]meridian = np.column_stack((x, y, z))meridians.append(meridian)# 创建纬线parallels = []for p in phi:x = radius * np.cos(theta) * np.sin(p) + center[0]y = radius * np.sin(theta) * np.sin(p) + center[1]z = radius * np.cos(p) * np.ones_like(theta) + center[2]parallel = np.column_stack((x, y, z))parallels.append(parallel)# 创建线集合line_set = o3d.geometry.LineSet()points = np.vstack(meridians + parallels)lines = []for i in range(len(meridians)):lines.extend([(i*resolution+j, i*resolution+(j+1)%resolution) for j in range(resolution)])for i in range(len(parallels)):lines.extend([(len(meridians)*resolution+i*resolution+j, len(meridians)*resolution+i*resolution+(j+1)%resolution) for j in range(resolution)])line_set.points = o3d.utility.Vector3dVector(points)line_set.lines = o3d.utility.Vector2iVector(lines)line_set.paint_uniform_color([0, 1, 0])  # 绿色线框return line_setdef visualize_bounding_sphere_wireframe(points, center, radius):pcd = o3d.geometry.PointCloud()pcd.points = o3d.utility.Vector3dVector(points)pcd.paint_uniform_color([1, 0, 0])  # 红色点sphere_wireframe = create_sphere_wireframe(center, radius)# 可视化o3d.visualization.draw_geometries([pcd, sphere_wireframe])# 示例使用
np.random.seed(0)
points = np.random.rand(1000, 3) * 10center, radius = compute_bounding_sphere(points)print("包围球的中心:", center)
print("包围球的半径:", radius)visualize_bounding_sphere_wireframe(points, center, radius)

Pasted image 20240920215113

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

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

相关文章

VMware tools安装

1.安装VMware tools工具 2.将压缩文件拖到桌面再解压 3. 进入终端 4.输入sudo ./vmware-install.pl 5.等待即安装成功 6.可以选择自动调整大小 7.自行调试即可

Lucene 倒排索引原理详解:深入探讨相关算法设计

引言 随着互联网的快速发展&#xff0c;数据量呈现爆炸性的增长&#xff0c;如何从海量数据中快速准确地获取所需信息成为了一项挑战。全文搜索引擎的出现极大地解决了这个问题&#xff0c;而 Lucene 正是一款优秀的开源全文搜索引擎库。本文将深入探讨 Lucene 的核心技术之一…

为人机交互保持预见性丨基于G32A1445的T-BOX应用方案

T-BOX是一种集成了通信、计算和控制功能的车载信息处理终端&#xff0c;通过车辆与云端、移动网络等进行数据交互&#xff0c;用于车、人、外部环境的互联互通&#xff0c;支持车辆定位、车载通信、远程控制、故障诊断、数据传输、紧急呼叫等功能&#xff0c;帮助车辆实现更加智…

力扣(leetcode)每日一题 2332 坐上公交的最晚时间

题目&#xff1a; 给你一个下标从 0 开始长度为 n 的整数数组 buses &#xff0c;其中 buses[i] 表示第 i 辆公交车的出发时间。同时给你一个下标从 0 开始长度为 m 的整数数组 passengers &#xff0c;其中 passengers[j] 表示第 j 位乘客的到达时间。所有公交车出发的时间互…

长亭WAF绕过测试

本文的Bypass WAF 的核心思想在于&#xff0c;一些 WAF 产品处于降低误报考虑&#xff0c;对用户上传文件的内 容不做匹配&#xff0c;直接放行 0、环境 环境&#xff1a;两台服务器&#xff0c;一台配置宝塔面板&#xff0c;一台配置长亭雷池WAF 思路主要围绕&#xff1a;m…

【渐冻勇士的营养秘籍!这些营养素让爱更坚强】

Hey小伙伴们~&#x1f44b; 今天我们来聊聊一个温暖而坚强的话题——渐冻症患者的营养补充攻略&#xff01;&#x1f4aa; 在这个充满挑战的路上&#xff0c;合理的营养摄入就像是他们最坚实的盔甲&#xff0c;让爱与希望的光芒更加耀眼。✨ &#x1f308; ‌蛋白质&#xff1…

Altium Designer(AD)百度云下载与安装(附安装步骤)

在我们日常使用当中&#xff0c;Altium designer常常也被简称为AD&#xff0c;是一款一体化的电子产品开发系统软件&#xff0c;主要运行在Windows操作系统上。 我们通过Altium designer把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技…

商业终端架构技术-未来之窗行业应用跨平台架构

未来之窗行业应用跨平台架构 以下是对未来之窗行业应用跨平台架构中客户端的稳定优势和网页跨平台性质的扩展列举&#xff1a; 一、客户端的稳定优势&#xff1a; 1. 离线可用性 - 即使在没有网络连接的…

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿

AI与量化投资人才培养计划-连接职场 助力走在金融行业前沿 人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;量化投资已逐渐成为金融行业的新趋势&#xff0c;对专业人才的需求日益迫切。本文将深入探讨一项针对AI与量化投资的人才培养计划&#xff0c;旨在为金融专业…

电气自动化入门05:三相异步电动机的正反转点动控制电路

视频链接&#xff1a;3.2 电工知识&#xff1a;三相异步电动机的正反转点动控制电路_1_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p6&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.断路器及其选型 1.1断路器定义、分类、表示符号 1.2.断路器功能、…

克隆GitHub仓库中的一个文件夹

要只克隆GitHub仓库中的一个文件夹&#xff0c;你可以使用 git sparse-checkout 功能。以下是具体步骤&#xff1a; 克隆仓库&#xff08;使用 --no-checkout 选项&#xff0c;避免下载所有内容&#xff09;&#xff1a; git clone --no-checkout <仓库地址> 进入克隆的…

[产品管理-29]:NPDP新产品开发 - 27 - 战略 - 分层战略与示例

目录 1. 公司战略 2. 经营战略 3. 创新战略 4. 新产品组合战略 5. 新产品开发战略 战略分层是企业规划和管理的重要组成部分&#xff0c;它涉及不同层级的战略制定和实施。以下是根据您的要求&#xff0c;对公司战略、经营战略、创新战略、新产品组合战略、新产品开发战略…

【CSS Tricks】如何做一个粒子效果的logo

效果展示 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>粒子效果Logo</title>…

uniapp使用uview2上传图片功能

官网地址Upload 上传 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 前提&#xff0c;需要下载vuew2插件 <view class"upload"><view class"u-demo-block__content"><view class"u-page__upload-item"&…

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制&#xff08;防止网络波动&#xff09;2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】

CLI示例(V2R8至V2R19C00版本):直连二层组网直接转发【AP+上层网络,增加AP下行口有线接入】 适用于:V200R008至V200R019C00版本的AC,以及有空闲以太网口的AP。 说明:本示例基于“直连二层组网直接转发【AP+AC+出口网关】”场景来介绍如何增加AP下行口有线接入。 业务需求…

SPI 详解

介绍 串行外设接口是微控制器用来与外设&#xff08;如 SRAM、SD 卡、移位寄存器、传感器等&#xff09;通信的最常见通信协议之一。它是一种同步、全双工、基于主从的协议。它支持高速数据传输&#xff0c;并且 SPI 协议中的数据速度 (bps) 和时钟频率 (Hz) 之间存在直接关系…

[Redis][Hash]详细讲解

目录 0.前言1.常见命令1.HSET2.HGET3.HEXISTS4.HDEL5.HKEYS6.HVALS7.HGETALL8.HMGET9.HLEN10.HSETNX11.HINCRBY12.HINCRBYFLOAT 2.内部编码1.ziplist(压缩链表)2.hashtable(哈希表) 3.使用场景4.缓存方式对比1.原⽣字符串类型2.序列化字符串类型3.哈希类型 0.前言 在Redis中&am…

帧率和丢帧分析理论

一、丢帧问题概述 应用丢帧通常指的是在应用程序的界面绘制过程中&#xff0c;由于某些原因导致界面绘制的帧率下降&#xff0c;从而造成界面卡顿、动画不流畅等问题。以60Hz刷新率为例子&#xff0c;想要达到每秒60帧&#xff08;即60fps&#xff09;的流畅体验&#xff0c;每…

鹏哥C语言复习——函数栈帧的创建和销毁

目录 演示用代码&#xff1a; 提示&#xff1a;后文讲解时后缀为h的指的是16进制表示 疑惑1&#xff1a;自定义函数、库函数都是在main函数内部调用&#xff0c;那么是什么调用了main函数呢&#xff1f; 疑惑2&#xff1a;如何观察ebp、esp等寄存器的运行&#xff1f; 疑惑…