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

【编程实践】点云曲率计算与可视化

基于Open3D和kNN的点云曲率计算与可视化,按下面指标定义的曲率

输入数据

  • 输入数据
    点云文件ply或pcd,加载为点云对象

指标定义

  • 此处曲率定义:采用基于点云PCA协方差分析的局部曲率估计方法。对于每个点,其曲率定义为:
    κ=λ1λ1+λ2+λ3\kappa = \frac{\lambda_{1}}{\lambda_{1}+\lambda_{2}+\lambda_{3}}κ=λ1+λ2+λ3λ1
    其中λ1\lambda_{1}λ1是协方差矩阵最小特征值,反映法向方向上的变化程度。该指标不具备严格几何意义的主曲率属性,但在点云中广泛应用于反映局部几何尖锐程度和表面变化趋势。

数学处理过程

  1. 邻域搜索(K-Nearest Neighbour)
  • 对每个点pip_{i}pi
    • 使用KD树查找其最近的k个临近点,点本身也被包含在邻域中;
    • 得到临近点集N(pi)={pi1,pi2,...,pik}\mathscr{N}(p_i)=\{p_{i1},p_{i2},...,p_{ik}\}N(pi)={pi1,pi2,...,pik} ,对于某个点pip_{i}pi有k个邻接点。
  1. 协方差矩阵计算
    对于每个邻域点集N(pi)\mathscr{N}(p_i)N(pi),计算其三维坐标协方差矩阵:
    Ci=Cov(N(pi))∈R3×3C_i = Cov(\mathscr{N}(p_i)) \in \mathbb{R^{3 \times 3}} Ci=Cov(N(pi))R3×3
    即:
    Ci=1k∑j=1k(pij−p‾i)(pij−p‾i)TC_i = \frac{1}{k}\sum^{k}_{j=1}(p_{ij}-\overline{p}_{i})(p_{ij}-\overline{p}_{i})^{T}Ci=k1j=1k(pijpi)(pijpi)T
    其中,p‾i\overline{p}_{i}pi是邻域点的均值向量。

  2. 特征值分级(Eigen Decomposition)
    计算协方差矩阵的特征值λ1\lambda_{1}λ1λ2\lambda_{2}λ2λ3\lambda_{3}λ3并排序:
    λ1≤λ2≤λ3\lambda_{1} \leq \lambda_{2} \leq \lambda_{3}λ1λ2λ3
    特征值代表该邻域点云在主轴方向上的分布方差。
    注:此处写的是数学上的标准形式1/k,属于有偏估计;实际适用了numpy的无偏估计1/(k-1).

  3. 曲率估计
    使用下面公式估算每个点的局部曲率:
    κi=λ1∑(λi)+ϵ\kappa_{i} = \frac{\lambda_{1}}{\sum(\lambda_{i})+ \epsilon}κi=(λi)+ϵλ1
    其中,λ1\lambda_{1}λ1为最小特征值,表示法向方向上的变化;分母为总变化量,归一化;ϵ\epsilonϵ为防止分母为0加的小常数。

曲率可视化(颜色映射)

  • 对所有点的曲率值κi\kappa_{i}κi进行归一化:
    κinorm=κi−min⁡(κ)max⁡(κ)−min⁡(κ)+ϵ\kappa^{\text{norm}}_{i} = \frac{\kappa_{i}-\min(\kappa)}{\max{(\kappa)}-\min{(\kappa)}+\epsilon}κinorm=max(κ)min(κ)+ϵκimin(κ)
  • 将归一化值使用Matplotlib的 jet 颜色映射为RGB颜色:
    colori=jet(κinorm)\text{color}_{i} = jet(\kappa^{\text{norm}}_{i})colori=jet(κinorm)
  • 将颜色赋值回Open3D点云对象用于可视化。

import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt# 加载点云
pcd = o3d.io.read_point_cloud("Result.ply")
# 构建KD树
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
# ---- 曲率计算函数(基于kNN) ----
def compute_curvature(pcd, knn=30):points = np.asarray(pcd.points)curvatures = []for i in range(len(points)):_, idx, _ = pcd_tree.search_knn_vector_3d(points[i], knn)neighbors = points[idx]covariance = np.cov(neighbors.T)eigvals, _ = np.linalg.eigh(covariance)eigvals = np.sort(eigvals)curvature = eigvals[0] / (np.sum(eigvals) + 1e-10)  # 避免除0curvatures.append(curvature)return np.array(curvatures)
# ---- 计算曲率 ----
curvatures = compute_curvature(pcd, knn=20)
# ---- 映射为颜色(使用matplotlib colormap) ----
norm_curvatures = (curvatures - np.min(curvatures)) / (np.max(curvatures) - np.min(curvatures) + 1e-10)
colors = plt.cm.jet(norm_curvatures)[:, :3]  # 只取 RGB,不要 alpha
pcd.colors = o3d.utility.Vector3dVector(colors)
# ---- 可视化 ----
o3d.visualization.draw_geometries([pcd])# ---- 可选:保存带颜色的点云 ----
# o3d.io.write_point_cloud("curvature_colored.ply", pcd)

计算结果可视化:
在这里插入图片描述

http://www.dtcms.com/a/315358.html

相关文章:

  • Pimpl惯用法
  • 【秋招笔试】2025.08.03虾皮秋招笔试-第二题
  • [GYCTF2020]FlaskApp
  • 0804 进程
  • 【笔记】重学单片机(51)(下)
  • 数据结构——并查集及C++实现
  • Javascript面试题及详细答案150道(046-060)
  • 5天从0到1!用阿里Qwen3-Coder开发故障调度指挥室系统,运维也能搞定开发
  • 嵌入式 C 语言入门:函数指针基础笔记 —— 从计算器优化到指针本质
  • 文本转语音(TTS)脚本
  • 【项目实践】在系统接入天气api,根据当前天气提醒,做好plan
  • C语言的控制语句
  • 16day-人工智学习-机器学习-特征工程
  • 【世纪龙科技】虚拟技术助力职教汽车自动变速器拆装虚拟实训软件
  • RFID技术在汽车倍速链中的应用:驱动智能制造的隐形引擎
  • Windows/Linux入侵排查
  • CPP学习之多态
  • Python高频元素分析技术:高效找出序列中出现次数最多的元素
  • 【Unity3D实例-功能-镜头】第三人称视觉
  • FeiQ飞秋安装教程:FeiQ.1060559168 详细安装步骤(附注意事项)​
  • 【QT】常⽤控件详解(三)常用按钮控件PushButton RadioButton CheckButton Tool Button
  • 茗鹤工业低代码可视化技术开发平台
  • 网络相关命令
  • 全国计算机二级C语言二级考试通关笔记
  • 风光储并网协同运行simulink仿真模型实现
  • [找出字符串中第一个匹配项的下标]
  • MiDSS复现
  • Codeforces Round 1010 (Div. 2, Unrated)
  • 8.4IO进程线程——进程
  • MySQL 基本操作入门指南