当前位置: 首页 > news >正文

open3D学习笔记

这里写自定义目录标题

  • 核心3D数据结构
    • 1.1 PointCloud(点云)
      • 最近邻搜索 (KNN/Radius) 与空间索引(KDTree/Octree)
      • 法线估计 (Normal Estimation)
      • 聚类分割 (基于欧氏距离的聚类)
    • 1.2 TriangleMesh (三角形网格)
      • 泊松表面重建 (Poisson Surface Reconstruction)
      • 滚球法 (Ball-Pivoting Algorithm - BPA)
      • 网格简化 (Mesh Simplification)
    • 1.3 VoxelGrid (体素网格)
      • 体素化 (Voxelization)
      • 形态学操作 (Morphological Operations)
    • 1.4 LineSet (线集)
      • 从网格创建线段集(提取网格的边)
      • 从点对创建线段集
      • 线段集的可视化
    • 1.5 总结与关系
  • 输入/输出(I/O)
  • 可视化
  • 几何处理
    • 4.1 体素下采样 (Voxel Downsampling)
    • 4.2 统计离群点去除 (Statistical Outlier Removal - SOR)
    • 4.3 半径离群点去除(Radius Outlier Removal, ROR)
    • 4.4 FPFH (Fast Point Feature Histograms)
    • 4.5 SHOT (Signature of Histograms of Orientations)
    • 4.6 法线估计 (Normal Estimation)
    • 4.7 泊松表面重建 (Poisson Surface Reconstruction)
    • 4.8 总结
  • 配准(Registration)
    • 5.1精配准的基石:迭代最近点算法 (ICP)
    • 5.2 粗配准:基于RANSAC的全局配准
    • 5.3 其他重要功能与评估
    • 5.4 完整配准流程建议
  • 3D机器学习
  • 渲染
  • 物理模拟
  • 数据处理管道

核心3D数据结构

1.1 PointCloud(点云)

  • 原理:点云是最基础、最直接的 3D 数据表示形式,直接来源于大多数 3D 传感器。它记录了物体表面一系列采样点的三维坐标 (x, y, z),并可扩展存储每个点的颜色 (r, g, b)、法线 (nx, ny, nz)、强度等属性。
    在这里插入图片描述
import open3d as o3d
import numpy as np# 创建一个简单的点云
points = np.random.rand(1000, 3)  # 1000个随机点
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)# 估计法线(关键算法)
# 使用 K近邻 策略,为点云 pcd 中的每一个点,计算其最近 30 个点,并基于这些点来估计该点的法向量。
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamKNN(knn=30)) # 可视化
o3d.visualization.draw_geometries([pcd], point_show_normal=True)

在这里插入图片描述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

最近邻搜索 (KNN/Radius) 与空间索引(KDTree/Octree)

在这里插入图片描述
在这里插入图片描述

法线估计 (Normal Estimation)

原理
基于主成分分析 (PCA)。核心思想:一个点及其邻域点可以拟合出一个局部微平面。这个平面的法线方向就是该点的法线方向。

  1. 邻域查询:对于点 p i p_i pi,利用 KDTree 找到其 K 个最近邻点 N ( i ) = p i 1 , p i 2 , . . . , p i k N(i) = {p_{i1}, p_{i2}, ..., p_{ik}} N(i)=pi1,pi2,...,pik
  2. 计算质心:计算邻域点的质心(中心点): p ˉ = 1 k ∑ j = 1 k p i j \bar{p} = \frac{1}{k} \sum_{j=1}^{k} p_{ij} pˉ=k1j=1kpij
  3. 构建协方差矩阵:计算协方差矩阵 C C C,它描述了邻域点围绕质心的分布情况: C = 1 k ∑ j = 1 k ( p i j − p ˉ ) ⋅ ( p i j − p ˉ ) T C = \frac{1}{k} \sum_{j=1}^{k} (p_{ij} - \bar{p}) \cdot (p_{ij} - \bar{p})^T C=k1j=1k(pijpˉ)(pijpˉ)T
  4. PCA 分解:对协方差矩阵 C C C 进行特征值分解,得到特征值 λ 1 , λ 2 , λ 3 \lambda_1, \lambda_2, \lambda_3 λ1,λ2,λ3( λ 1 ≥ λ 2 ≥ λ 3 ≥ 0 \lambda_1 \geq \lambda_2 \geq \lambda_3 \geq 0 λ1λ2λ30) 和对应的特征向量 v 1 ⃗ , v 2 ⃗ , v 3 ⃗ \vec{v_1}, \vec{v_2}, \vec{v_3} v1 ,v2 ,v3
  5. 法线确定:最小特征值 λ 3 \lambda_3 λ3 对应的特征向量 v 3 ⃗ \vec{v_3} v3 即为法线方向。因为数据在法线方向上的变化最小(方差最小),而在切平面上变化最大。
    在这里插入图片描述
import open3d as o3d
import numpy as np# 生成示例点云(一个平面加上一些噪声,法线应大致指向z轴正方向)
mesh = o3d.geometry.TriangleMesh.create_box(width=2.0, height=1.0, depth=0.2)
mesh.translate((-1.0, -0.5, -0.1)) # 平移使原点在中心
pcd = mesh.sample_points_poisson_disk(500) # 从网格采样生成点云# 估计法线
# 使用KNN策略,k=30
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamKNN(knn=30))# 为了可视化效果,统一法线方向(使其指向[0,0,1]大致方向)
pcd.orient_normals_to_align_with_direction(orientation_reference=np.array([0., 0., 1.]))# 可视化:按法线方向着色
# 将法向量([-1,1])映射到RGB颜色([0,1])进行可视化
pcd.paint_uniform_color([0.5, 0.5, 0.5]) # 先设置一个基础灰色
o3d.visualization.draw_geometries([pcd],point_show_normal=True,window_name="Point Cloud with Normals")# 访问估计的法线
normals = np.asarray(pcd.normals)
print(f"First 5 normals:\n{normals[:5]}")

在这里插入图片描述

聚类分割 (基于欧氏距离的聚类)

在这里插入图片描述

import open3d as o3d
import numpy as np# 创建包含两个明显分开的簇的点云
points1 = np.random.rand(100, 3) * 0.5 + np.array([0, 0, 0])  # 簇1,围绕(0,0,0)
points2 = np.random.rand(100, 3) * 0.5 + np.array([2, 2, 2])  # 簇2,围绕(2,2,2)
points = np.vstack((points1, points2))pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)# 可视化原始点云
o3d.visualization.draw_geometries([pcd], window_name="Original Point Cloud")# 使用Open3D进行基于欧氏距离的聚类
# 参数1: eps - 邻域搜索半径
# 参数2: min_points - 形成一个簇所需的最少点数
labels = np.array(pcd.cluster_dbscan(eps
http://www.dtcms.com/a/353294.html

相关文章:

  • 微软研究院最新tts模型VIBEVOICE解析
  • 配送算法16 A Deep Reinforcement Learning Approach for the Meal Delivery Problem
  • postgreSql远程连接数据库总是超时断开?
  • c#联合vision master 的基础教程
  • linux安装containerd
  • 如何使用 Xshell 8 连接到一台 CentOS 7 电脑(服务器)
  • MySQL 8 与 PostgreSQL 17 对比分析及迁移指南
  • 学习 Android (十七) 学习 OpenCV (二)
  • 【PHP】数学/数字处理相关函数汇总,持续更新中~
  • 极限RCE之三字节RCE
  • 嵌入式学习日记(35)TCP并发服务器构建
  • 指纹手机应用核心技术解析:从识别到智能交互
  • 搭建域服务器
  • 毕业项目推荐:28-基于yolov8/yolov5/yolo11的电塔危险物品检测识别系统(Python+卷积神经网络)
  • ChatGPT登录不进怎么办?
  • NumPy广播机制:高效数组运算的秘诀
  • 预测模型及超参数:2.传统机器学习:PLS及其改进
  • 守术,明法,悟道
  • 欧盟《人工智能法案》生效一年主要实施进展概览(二)
  • 如何借助文档控件 TX Text Control 轻松优化 PDF 文件大小?
  • 中科大携手智源发布 BGE-Reasoner:引领推理式信息检索新高度
  • AI数据治理:战略选择与伦理平衡
  • C6.4:晶体管模型
  • 语言切换时广播没有监听到语言变化
  • 从传统到创新:用报表插件重塑数据分析平台
  • OpenTelemetry 在 Spring Boot 项目中的3种集成方式
  • SciPy科学计算与应用:SciPy应用实战-数据分析与工程计算
  • SpringBoot集成 DeepSeek 对话补全功能
  • 安全建设之SLA指标(服务等级协议)
  • Linux基础优化(Ubuntu、Kylin)