SVD求解两个点集之间的刚体运动,即旋转矩阵和平移向量。

问题描述

给出两个点集A和B,求解点集之间的刚体变化,包含scale,rotation,translate。使其A经过变换之后,可以和B在空间上对齐。

原理

SVD可以用于求解上述问题。
假设有A点集 A ∈ R n × 3 A \in R^{n\times 3} ARn×3, B点集 B ∈ R n × 3 B \in R^{n \times 3} BRn×3,优化的目标是:
a r g m i n R , t   ∣ ∣ R × A + T − B ∣ ∣ \underset{R, t}{argmin} \, ||R \times A + T - B|| R,targmin∣∣R×A+TB∣∣

应用

比如说有两个脸的mesh
SVD求解两个点集之间的刚体运动,即旋转矩阵和平移向量。_第1张图片
他们在空间中不能对的上,贴合程度不高。通过标定一些固定点
SVD求解两个点集之间的刚体运动,即旋转矩阵和平移向量。_第2张图片
即额头的这些点,之所以选择这些点,因为他们基本不随着脸部运动而变化。
然后将选出来的两个点集分别作为src,dst。将src向dst对齐。

def slove_RT_by_SVD(src, dst):
    src_mean = src.mean(axis=0, keepdims=True)
    dst_mean = dst.mean(axis=0, keepdims=True)

    src = src - src_mean # n, 3
    dst = dst - dst_mean
    H = np.transpose(src) @ dst

    U, S, Vt = np.linalg.svd(H)
    R = Vt.T @ U.T 

 
    if np.linalg.det(R) < 0:
        print("Reflection detected")
        Vt[2, :] *= -1
        R = Vt.T & U.T

    t = -R @ src_mean.T + dst_mean.T  # 3, 1

    return R, t

之所以判断行列式,其原因去参考的【原版原理介绍】中寻找。
然后就能得到极其贴合的两个mesh
SVD求解两个点集之间的刚体运动,即旋转矩阵和平移向量。_第3张图片

参考

利用SVD求得两个对应点集合的旋转矩阵R和转移矩阵t的数学推导
原版原理介绍

你可能感兴趣的:(机器学习,Python,矩阵,算法,线性代数)