OBB-最小外接矩形包围框-原理-代码实现

news2024/9/20 16:17:50

前言

  • 定义:OBB是相对于物体方向对齐的包围盒,不再局限于坐标轴对齐,因此包围点云时更加紧密。
  • 优点:能够更好地贴合物体形状,减少空白区域。
  • 缺点:计算较为复杂,需要计算物体的主方向,进行旋转和缩放变换。

Pasted image 20240920104735

算法原理

实现OBB通常涉及以下步骤:

  1. 计算凸包(Convex Hull)
  2. 使用主成分分析(Principal Component Analysis,简称PCA)找到最佳的旋转方向
  3. 根据这些方向确定包围盒的边界

步骤一:计算凸包

凸包是一组点的最小凸多边形,包含所有点,并且所有点都在多边形的边界上或内部。可以使用scipy库中的ConvexHull函数来计算。

import numpy as np
from scipy.spatial import ConvexHull
# 生成数据
mean = [0, 0]
cov = [[3, 1], [1, 2]]
points = np.random.multivariate_normal(mean, cov, 300)

# 计算凸包
convex_hull = ConvexHull(points)
# 可视化
plt.figure(figsize=(10, 8))
plt.scatter(points[:, 0], points[:, 1], s=10, alpha=0.5, label='Points')

Pasted image 20240920105021
图 展示了图包得到的最外层点及其点之间的连线

步骤二:主成分分析(PCA)

PCA可以帮助我们找到数据的主方向。通过分析凸包顶点的协方差矩阵,我们可以得到主要的方向,这些方向定义了OBB的方向。

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(points[convex_hull.vertices])  # 仅对凸包顶点进行PCA

步骤三:根据PCA方向计算OBB

根据PCA的结果,我们可以确定OBB的方向。然后,我们需要计算在这些方向上点的投影,以此来确定矩形的边界。

# OBB计算函数
def compute_obb(points):
    # 使用PCA找到数据的主成分方向
    pca = PCA(n_components=2)
    pca.fit(points)
    
    # 得到主轴
    eigen_vectors = pca.components_
    eigen_values = pca.explained_variance_
    
    # 将点投影到主轴上
    projected_points = np.dot(points, eigen_vectors.T)
    
    # 计算包围盒的边界
    min_proj = np.min(projected_points, axis=0)
    max_proj = np.max(projected_points, axis=0)
    
    # 通过主轴和包围盒的边界重构OBB顶点
    obb_vertices = np.array([
        [min_proj[0], min_proj[1]],
        [min_proj[0], max_proj[1]],
        [max_proj[0], max_proj[1]],
        [max_proj[0], min_proj[1]]
    ])
    
    # 将OBB顶点从PCA空间转换回原始空间
    obb_vertices = np.dot(obb_vertices, eigen_vectors)
    
    return obb_vertices
obb_vertices = compute_obb(points)

上述代码定义了计算OBB的整个过程,从计算凸包到应用PCA,最后确定边界框的角。每步都是基于数学原理进行建模,确保能找到最合适的包围盒。
Pasted image 20240920104735

完整代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from scipy.spatial import ConvexHull

# OBB计算函数
def compute_obb(points):
    # 使用PCA找到数据的主成分方向
    pca = PCA(n_components=2)
    pca.fit(points)
    
    # 得到主轴
    eigen_vectors = pca.components_
    eigen_values = pca.explained_variance_
    
    # 将点投影到主轴上
    projected_points = np.dot(points, eigen_vectors.T)
    
    # 计算包围盒的边界
    min_proj = np.min(projected_points, axis=0)
    max_proj = np.max(projected_points, axis=0)
    
    # 通过主轴和包围盒的边界重构OBB顶点
    obb_vertices = np.array([
        [min_proj[0], min_proj[1]],
        [min_proj[0], max_proj[1]],
        [max_proj[0], max_proj[1]],
        [max_proj[0], min_proj[1]]
    ])
    
    # 将OBB顶点从PCA空间转换回原始空间
    obb_vertices = np.dot(obb_vertices, eigen_vectors)
    
    return obb_vertices

np.random.seed(42)
mean = [0, 0]
cov = [[3, 1], [1, 2]]
points = np.random.multivariate_normal(mean, cov, 300)

# 计算OBB顶点
obb_vertices = compute_obb(points)

# 计算凸包
convex_hull = ConvexHull(points)

# 可视化点云、OBB和凸包
plt.figure(figsize=(10, 8))
plt.scatter(points[:, 0], points[:, 1], s=10, alpha=0.5, label='Points')

# 绘制OBB
obb_polygon = np.vstack([obb_vertices, obb_vertices[0]])  # 闭合OBB多边形
plt.plot(obb_polygon[:, 0], obb_polygon[:, 1], 'r-', linewidth=2, label='OBB')

# 绘制凸包
for simplex in convex_hull.simplices:
    plt.plot(points[simplex, 0], points[simplex, 1], 'g--', linewidth=1)

plt.plot(points[convex_hull.vertices, 0], points[convex_hull.vertices, 1], 'g-', linewidth=2, label='Convex Hull')
plt.scatter(points[convex_hull.vertices, 0], points[convex_hull.vertices, 1], color='green')

plt.title('OBB and Convex Hull Visualization')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend()
plt.axis('equal')
plt.grid(True)
plt.show()

利用Open3D使用OBB算法

import open3d as o3d
import numpy as np

# 读取点云 txt 文件,假设文件名为 'point_cloud.txt'
file_path = './data/5.txt'

# 使用 numpy 读取数据
point_cloud_data = np.loadtxt(file_path)

# 提取点的坐标 (x, y, z) 和颜色 (r, g, b)
points = point_cloud_data[:, :3]
colors = point_cloud_data[:, 3:] / 255.0  # Open3D expects colors in [0, 1] range

# 创建 Open3D 点云对象
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
pcd.colors = o3d.utility.Vector3dVector(colors)


# 计算AABB(轴对齐包围盒)
obb = pcd.get_oriented_bounding_box()
axis = o3d.geometry.TriangleMesh.create_coordinate_frame()


# 可视化点云和AABB
obb.color = (0, 1, 0)  
o3d.visualization.draw_geometries([pcd,obb])


可视化结果:
Pasted image 20240920105437

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

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

相关文章

二叉树的遍历【C++】

对于二叉树系列的题,必须要会遍历二叉树。 遍历的有:深度优先:前序、中序、后序,广度优先:层序遍历 什么序是指处理根节点在哪个位置,比如前序是指处理节点顺序:根左右。 接下来要说明的是&…

深入浅出Docker

1. Docker引擎 Docker引擎是用来运行和管理容器的核心软件。通常人们会简单的将其指代为Docker或Docker平台。 基于开放容器计划(OCI)相关的标准要求,Docker引擎采用了模块化的设计原则,其组件是可替换的。 Docker引擎由如下主…

从理论到实践:全面指导企业实现数字化转型的战略路径

全球企业数字化转型的必然性 在全球范围内,数字化转型成为了企业战略中的核心命题。随着云计算、大数据、人工智能等新兴技术的快速发展,企业的运营模式、管理体系及客户体验正在发生深刻的变革。数字技术不仅为企业带来了新的商业机会,还使…

【Elasticsearch】-图片向量化存储

需要结合深度学习模型 1、pom依赖 注意结尾的webp-imageio 包&#xff0c;用于解决ImageIO.read读取部分图片返回为null的问题 <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.7.0-0</versio…

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

海报制作哪个软件好?这些在线工具不容错过

国庆节的脚步越来越近&#xff0c;不少公司正计划利用这个时机开展一些特别的庆典活动。 在这些活动中&#xff0c;海报作为一种传统的宣传方式&#xff0c;仍然是不可或缺的。但在制作海报时&#xff0c;我们可能会遇到创意瓶颈、时间限制或者预算约束等问题。 幸运的是&…

高棉语翻译神器上线!中柬互译,OCR识别,语音翻译一应俱全,《柬埔寨语翻译通》App

全新的高棉语翻译神器已经正式上架&#xff01; 无论你是安卓还是iOS用户&#xff0c;现在都可以轻松开始使用&#xff0c;开启你的翻译之旅&#xff01; 这款应用不仅仅是一个简单的翻译工具&#xff0c;它还支持中文与高棉语的双向翻译。翻译结果可以语音播放&#xff0c;翻…

AI服务器是什么?为什么要用AI服务器?

AI服务器的定义 AI服务器是一种专门为人工智能应用设计的服务器&#xff0c;它采用异构形式的硬件架构&#xff0c;通常搭载GPU、FPGA、ASIC等加速芯片&#xff0c;利用CPU与加速芯片的组合来满足高吞吐量互联的需求&#xff0c;为自然语言处理、计算机视觉、机器学习等人工智…

企业微信-前往服务商后台页面对接解决方案

序 我会告诉你在哪里点我会告诉你在哪里配置点下去他只返回auth_code的&#xff0c;我怎么登录 正文 他是在这个位置 是这样&#xff0c;应用授权安装第三方应用后&#xff0c;企业微信&#xff08;管理员角色&#xff09;是可以从pc端企业后台点第三方应用的。 如果我没记…

【余弦相似度】

余弦相似度 又称为余弦距离&#xff0c;利用两个向量之间的夹角的余弦值来衡量两个向量的余弦相似度&#xff0c;两个向量夹角越小&#xff0c;余弦值越接近1。 向量模&#xff08;向量长度&#xff09;计算方法&#xff1a; n维向量的相似度计算&#xff1a; 余弦相似度的取…

黑盒测试 | 挖掘.NET程序中的反序列化漏洞

通过不安全反序列化漏洞远程执行代码 img 今天&#xff0c;我将回顾 OWASP 的十大漏洞之一&#xff1a;不安全反序列化&#xff0c;重点是 .NET 应用程序上反序列化漏洞的利用。 &#x1f4dd;$ _序列化_与_反序列化 序列化是将数据对象转换为字节流的过程&#xff0c;字节流…

Entity更新坐标不闪烁需采用setCallbackPositions方法赋值

问题描述&#xff1a; 1.new mars3d.graphic.PolygonEntity({在更新点位高度模拟水面上身的时候&#xff0c;会存在闪烁 2.当把addDemoGraphic4添加到图层后&#xff0c;addDemoGraphic1水位变化不闪烁&#xff0c;把addDemoGraphic4注释后&#xff0c;addDemoGraphic1闪烁。…

UI自动化测试的边界怎么定义?

标题&#xff1a;定义UI自动化测试的边界&#xff1a;从0到1的详细指南 引言&#xff1a; UI自动化测试是现代软件开发过程中至关重要的一环。为了确保自动化测试的有效性和准确性&#xff0c;我们需要明确定义测试的边界。本文将从0到1为您提供一篇详细且规范的指南&#xf…

基于YOLOv8/YOLOv9/YOLOv10的河道漂浮物检测识别系统

摘要&#xff1a; 河道漂浮物检测识别是指利用技术手段自动识别河流、湖泊等水体表面的漂浮垃圾或物体的过程。随着环境保护意识的增强和技术的进步&#xff0c;河道漂浮物检测已经成为水环境保护和管理的重要组成部分。这项技术的应用可以帮助及时发现污染源&#xff0c;采取措…

一些线上常用排查问题的命令

排查CPU过高时使用到的一些命令 top free df top命令 top 命令是一个动态的实时视图&#xff0c;显示系统的整体运行状况&#xff0c;包括 CPU 使用率、内存使用情况、进程信息等。 free 命令 free 命令用于显示系统中物理内存和交换内存的使用情况。 df 命令 df 命令用…

纯前端表格导出Excel

先写好两个js文件 直接复制粘贴 文件目录是这样的 Bolb.js /* eslint-disable */ /* Blob.js* A Blob implementation.* 2014-05-27** By Eli Grey, http://eligrey.com* By Devin Samarin, https://github.com/eboyjr* License: X11/MIT* See LICENSE.md*//*global self, …

Vuex 入门与实战

引言 Vuex 是 Vue.js 官方推荐的状态管理库&#xff0c;它可以帮助我们更好地管理 Vue 应用的状态。在大型应用中&#xff0c;组件之间的状态共享和通信是一个非常重要的问题&#xff0c;而 Vuex 提供了一种优雅的解决方案。 在 Vue 应用中&#xff0c;数据的流动一般是单向的…

PCA贡献率

什么是 PCA&#xff1f; PCA&#xff08;Principal Component Analysis, 主成分分析&#xff09;是一种常用的数据降维技术。它通过找到一组新的互不相关的正交轴&#xff08;主成分&#xff09;&#xff0c;将高维数据映射到低维空间。这些新轴是按照数据的方差大小排列的&am…

让Tkinter更美观:教你同步Tkinter窗口与弹窗图标(Tkinter同步主窗口与Messagebox的图标)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 步骤1:主窗口图标📝 步骤2:messagebox 图标📝 示例代码📝 实现原理与代码解释⚓️ 相关链接 ⚓️📖 介绍 📖 你有没有注意到,在开发软件图形界面时,会需要弹出一些提示框,而这些提示框的图标总…

阿里国际发布最新版多模态大模型Ovis,拿下开源第一

看一眼菜品图就知道怎么做、能给植物看病、能把手写英文准确翻译成中文、还能精准分析财报数据……多模态能力再次升级&#xff01;阿里国际AI团队发布了一款多模态大模型Ovis&#xff0c;在图像理解任务上不断突破极限&#xff0c;多种具体的子类任务中均达到了SOTA&#xff0…