法向量估计
- 1. 求解点P法向量的原理
- 2. 法向量估计的证明
- 3. 为什么求点P的法向量,需要使用以P为中心的邻域内的点?
- 4. 法向量估计的应用和思考
- 5. 权重法向量估计
1. 求解点P法向量的原理
已知有一组点 P = ( p 1 , p 2 , p 3 , . . . , p n ) , p i ∈ R 3 P = (p_1,p_2,p_3,...,p_n),p_i \in R_3 P=(p1,p2,p3,...,pn),pi∈R3,求点 p 3 p_3 p3的法向量的通用步骤:
- 确定邻域:首先需要确定点 P 的邻域,即在点云中与点 P 相邻的点的集合。通常情况下,可以通过设置一个固定的半径或者固定数量的最近邻来定义邻域。
- 计算局部表面拟合:对于确定的邻域内的点,可以使用拟合曲面的方法来估计局部表面形状。常用的拟合方法包括最小二乘拟合、主成分分析(PCA)拟合等。这些方法可以得到一个与邻域内点最适合的平面、曲线或曲面。
- 计算法向量:通过拟合得到的局部表面形状,可以计算点 P 的法向量。对于平面拟合,法向量即为拟合平面的法向量;对于曲面拟合,可以通过对曲面方程求导得到法向量。
- 后处理:在计算法向量后,可以进行一些后处理操作,比如法向量的平滑化、去噪等,以提高法向量的质量和稳定性。
这里给出使用PCA求解的步骤和代码
- 确定领域,得到邻域内的所有点
- 求邻域内点组成的矩阵 M ∈ R n × 3 M \in R_{n \times 3} M∈Rn×3的协方差矩阵的奇异值分解
- 求左奇异值矩阵的特征向量,最小的特征值对应的特征向量即为所求
normals = []
radius = 0.05
leaf_size = 5
tree = KDTree(points,leaf_size)
near_point_idx = tree.query_radius(points,radius)#每一点的邻居点索引,包含自身点
for i in range(points.shape[0]):
point_near = points[near_point_idx[i]] #某一点的邻居点,
v = PCA(point_near)
normal = v[:,2]
normals.append(normal)
normals = np.asarray(normals)
2. 法向量估计的证明
为什么最小特征值对应的特征向量即为法向量方向
3. 为什么求点P的法向量,需要使用以P为中心的邻域内的点?
假设点P为这组点的中心,只要求所有点到点P的切平面的距离的L2范数最小,就说明这个切平面最接近这簇点的表面形状
4. 法向量估计的应用和思考
- 应用
分割,聚类,平面检测 - 思考半径选择太大,会受到不相关部分影响,导致法向量平滑;半径过小会容易受到噪声影响;半径不仅可以使用欧式空间邻域,同样可以使用其他尺度的邻域,包括反射率邻域,颜色邻域等;也可以根据周围点对点P的影响程度,在求法向量的时候为每个点加上权重
5. 权重法向量估计
也就是求
X
ˉ
W
X
ˉ
T
\bar{X} W \bar{X}^{T}
XˉWXˉT的最小特征向量,
X
ˉ
\bar{X}
Xˉ是一组输入向量的去中心化向量。