# 曲率

曲率(curvature)就是针对曲线上某个点的切线方向角对弧长的转动率,通过微分来定义,表明曲线偏离直线的程度。数学上表明曲线在某一点的弯曲程度的数值。

曲率

# 参数曲线的曲率公式

曲线的切线方向角:曲线在点PP 处的切线与xx 轴正向的夹角α\alpha

k=dαds=y(1+y2)3/2k=\frac{|d\alpha|}{ds}=\frac{|y''|}{(1+y'^2)^{3/2}}

适用于连续可导的函数曲线

  • ss 为弧长;
  • yy',y2y'^2 分别为函数的一阶导数和二阶导数。

局限性:需要函数的解析表达式 (如y=x2y=x²), 但点云数据(如 3D 扫描得到的离散点)没有显式的函数形式,无法直接计算导数。

# 点云曲率计算

  1. 邻域协方差矩阵(Covariance Matrix),构建协方差矩阵covcov.
  2. 特征值分解:计算协方差矩阵的特征值λ0λ1λ2λ_0≤λ_1≤λ_2 和特征向量。
  3. 曲率定义:曲率k=λ0/(λ0+λ1+λ2)k=λ_0 / (λ_0+λ_1+λ_2)

协方差矩阵

  • 协方差矩阵:描述点云局部几何特征,反映邻域点在法向方向上的离散程度。
  • 协方差矩阵计算:计算邻域点坐标的均值meanmean,然后计算邻域点坐标减去均值后的协方差矩阵covcov

协方差矩阵:

cov=1ki=1k(pimean)(pimean)Tcov = \frac{1}{k}\sum_{i=1}^{k}(p_i-mean)(p_i-mean)^T

  • pip_i 为邻域点坐标;
  • meanmean 为邻域点坐标的均值;
  • kk 为邻域点的数量。

# 特征值分解

  • 特征向量:代表邻域点分布的 “主方向”(即数据最分散的方向)。例如,若邻域点近似在一个平面上,特征向量会包括平面内的两个正交方向(主方向)和垂直于平面的方向。

  • 特征值:代表邻域点在对应主方向上的 “离散程度”(可理解为 “伸展幅度”)。特征值越大,说明数据在该方向上越分散。

    • 最小特征值λ0λ_0:对应数据最 “紧凑” 的方向(离散程度最小);
    • 最大特征值λ2λ_2:对应数据最 “伸展” 的方向(离散程度最大)。

# 曲率定义

几何意义

  • 当邻域点近似分布在平面上时,λ00λ_0≈0(法向方向无离散),曲率k0k≈0
  • 当邻域点位于边缘或尖点时,λ0λ_0 增大,曲率kk 较大。

实例:

基于曲率计算 T 型面的焊点

T型面

"9i65wsa

import open3d as o3d
import numpy as np
weld_pcd = o3d.io.read_point_cloud("2.ply")  # T 型平面点云数据
pcd_tree = o3d.geometry.KDTreeFlann(weld_pcd) # 构建 KD 树
curvatures = np.zeros(len(weld_pcd.points))  # 初始化曲率数组
for i in range(len(weld_pcd.points)):
    [k, idx, _] = pcd_tree.search_knn_vector_3d(weld_pcd.points[i], 20)  # 搜索邻域点
    if k < 3:
        continue
    points = np.asarray(weld_pcd.points)[idx, :] # 获取邻域点坐标
    mean = np.mean(points, axis=0) # 计算邻域点均值
    points_centered = points - mean # 中心化
    cov = np.dot(points_centered.T, points_centered) / k # 计算协方差矩阵
    eigenvalues, eigenvectors = np.linalg.eigh(cov) # 计算特征值
    curvatures[i] = eigenvalues[0] / (eigenvalues.sum() + 1e-10) # 计算曲率
threshold = np.percentile(curvatures, 98) # 计算曲率阈值
is_weld_point = curvatures > threshold # 判断是否为焊点
weld_points = np.asarray(weld_pcd.points)[is_weld_point] # 获取焊点坐标
 
dot_radius = 0.001 # 圆点半径,根据实际场景调整
dot_clouds = []
for point in weld_points:
    sphere = o3d.geometry.TriangleMesh.create_sphere(radius=dot_radius) # 创建球体
    sphere.translate(point)
    sphere.paint_uniform_color([1, 1, 0]) # 黄色圆点,可调整颜色
    dot_clouds.append(sphere)
o3d.visualization.draw_geometries([weld_pcd]+dot_clouds)

焊点

两种方法的联系
虽然公式形式不同,但两者的核心思想一致:曲率反映曲线 / 曲面的弯曲程度。

  • 参数曲线公式通过导数直接计算切线方向的变化率;
  • 点云方法通过邻域几何分析(协方差矩阵和特征值)间接估计弯曲程度。

# 其他点云曲率计算方法

  • 拟合局部曲面:对邻域点拟合二次曲面(如抛物面),然后计算曲面的曲率。
  • 法线变化率:通过相邻点的法线方向差异估计曲率。
  • 高斯映射:将点云投影到单位球面上,分析投影点的分布密度。