一. 奇异值分解在3D视觉中的应用

ICP问题的应用

ICP (Iterative Closest Point)迭代最近点在点云配准、手眼标定当中都有应用。

比如在点云配准中,两帧点云有n对对应的点,如何寻找欧式变换将这两组点重合,这就是ICP在点云配准中的应用。

image

再比如3D相机和机械臂的手眼标定,获得多个点在相机坐标系中的坐标Pc以及在机械臂坐标系中的坐标PB,然后将Pb和PC配准重合,就得到了相机坐标系和机械臂坐标系的欧式变换。

image

矩阵的奇异值分解 (SVD)

令矩阵\(A\in \mathbb{R}^{m \times n}\),存在两个正交矩阵(复数域则是酉矩阵)\(U\in \mathbb{R}^{m \times m}\)\(V\in \mathbb{R}^{n \times n}\),使得

\[A_{m\times n}=U_{m} \Sigma_{m \times n} V^T_{n} \]

式中,\(\Sigma =\begin{bmatrix}\Sigma_1 & 0\\0 & 0\end{bmatrix},\Sigma_{1} = \text{diag}(\sigma_1, \dots, \sigma_r)\)为r阶方阵,\(\sigma_i\) 为A的奇异值,且按大小降序排列,\(r=\text{rank}(A)\)

SVD求解迭代最近点 (ICP)

如下图1所示,有两个三维点的集合A和B,集合A中的点\(p_i\)和集合B中的点\(p_i'\)一一对应。

ICP问题就是寻找欧式变换 R, t,使得\(p_i = Rp_i'+t\)。即寻找一个欧式变换使得点集B经过此变换与点集A重合,如图2所示。

如果这里点集A是一帧点云,B是下一帧点云,那么ICP就是如何对这两帧点云进行配准。

如果这里点集A是相机坐标系中的点,点集B是在机械臂基坐标系下的点,那么这里ICP就是求解手眼标定问题。

image-20210713153443015

这里的推导过程参考了 K. S. ARUN, T. S. HUANG, AND S. D. BLOSTEIN. Least-Squares Fitting of Two 3-D Point Sets,省略了一些证明的部分,感兴趣的读者可以看看这篇文章。

构建最小二乘问题,我们的目标就是求解R, t使得下式最小二乘误差最小

\[\min_{R,t}{1 \over 2}\sum_i^n||p_i -(Rp_i'+t) ||^2_2 \]

我们使用每个点集的去质心坐标带入上面的最小二乘误差中,令A的质心为\(\bar p = {1 \over n} \sum_{i=1}^np_i\),A中每个点的去质心坐标表示为\(q_i = p_i -\bar p\),类似的,定义B的质心为\(\bar p' = {1 \over n} \sum_{i=1}^np_i'\),B中每个点的去质心坐标为\(q_i'=p_i' - \bar p'\)

将去质心坐标带入误差\(J=\sum_i^n||p_i -(Rp_i'+t) ||^2\),(这里我省略了二范数的下标),得到

\[J=\sum_i^n||q_i +\bar p - [R(q_i'+\bar p')+t] ||^2 \\ = \sum_i^n || q_i - Rq_i' + \bar p - (R \bar p' +t)||^2 \]

我们观察上式中,前面的部分\((q_i -Rq_i')\) 是点集A和旋转后的点集B的去质心坐标之差,表示了姿态的误差,后面的项 \(\bar p - (R \bar p' +t)\) 是点集A的质心和点集B质心的误差。而最小二乘法得到的 R, t 是保证两个点集的质心重合的,因此 \(\bar p - (R \bar p' +t) = 0\),误差变为(省略\(\sum\)上下标)

\[J = \sum|| q_i - Rq_i' ||^2\\ = \sum(q_i - Rq_i')^T(q_i - Rq_i')\\ = \sum(q_i^Tq_i - q_i^TRq_i' - q_i'^TR^Tq_i + q_i'^TR^TRq_i') \]

上式中,\(q_i^TRq_i'\)\(q_i'^TR^Tq_i\) 两项都是标量,可以合并;第四项中的\(R^TR=I\),于是上式简化为

\[J= \sum(q_i^Tq_i + q_i'^Tq_i' - 2q_i^TRq_i' ) \]

上面的误差中,只有 \(- 2q_i^TRq_i'\) 中含有优化变量,于是最小化上面的误差函数等效于最大化 \(F= \sum q_i^TRq_i'\)

\(q_i^TRq_i'\) 其实是个标量,我们利用矩阵的迹的性质 \(x^TAx = tr(Axx^T)\),得到

\[F = \sum q_i^TRq_i' = \text{tr}(R\sum q_i' q_i^T) \]

\(H=\sum q_i' q_i^T\),我们展开看\(\sum q_i' q_i^T = \sum(p_i'-\bar p')(p_i - \bar p)\)

如果我们以随机向量的观点来看的话,随机向量a用a(i)表示(可以理解为点集A中的点),随机向量b用p'(i)表示,a和b的协方差(统计中一般除以n-1)就是

\[Cov(a,b)=E\{[a(i)-\bar a][b(i) - \bar b]^T \} = {1 \over n}\sum_{i=1}^n[a(i)-\bar a ][b(i)- \bar b]^T \]

对比H矩阵展开的结果,我们发现H矩阵其实就是A和B点集中点的协方差乘以点的个数n。

对H进行奇异值分解,\(H=\sum q_i' q_i^T = U \Lambda V^T\),则可以求得旋转矩阵\(R=VU^T\)

再将求得的R带入\(\bar p - (R \bar p' +t) = 0\)中求得平移向量 t

案例讲解

下面我们用Python来实现一个SVD求解点对配准的案例

import numpy as np
from scipy import linalg
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from scipy.spatial.transform import Rotation

# Generate pointset A and B
A = np.random.rand(10,3)
# Random rotation and translation
R = Rotation.random().as_matrix()
print('Rotation matrix:\n ', R)
t = np.random.rand(3)
print('Translation vector:\n ', t)

B = []
for i in range(len(A)):
    p = R @ A[i] + t
    print(f'pa:{A[i]} -> pb:{p}')
    B.append(p)
B = np.array(B)

fig = plt.figure()
ax1 = Axes3D(fig)
ax1.scatter(A[:,0], A[:,1], A[:,2], c='r', label='A')
ax1.scatter(B[:,0], B[:,1], B[:,2], c='b', marker='x', label='B')
for i in range(len(A)):
    ax1.plot([A[i,0], B[i,0]], [A[i,1], B[i,1]], [A[i,2], B[i,2]], c='k', linewidth=0.5)
ax1.legend()
plt.show()

centroid_A = A.mean(axis=0)
centroid_B = B.mean(axis=0)
decenter_A = A - centroid_A
decenter_B = B - centroid_B

sum = np.zeros((3,3))
for i in range(len(A)):
    sum += np.outer(decenter_A[i], decenter_B[i])

U, S, Vt = linalg.svd(sum) # sum = U @ S @ Vt
R_hat = Vt.T @ U.T
t_hat = centroid_B - R_hat @ centroid_A
print('Estimated rotation matrix:\n', R_hat)
print('Estimated tranlation vector:\n', t_hat)

图3为随机生成的点集A中的十个点,以及经过随机变换后的点集B中的十个点,连线表明了点之间的对应关系。

图4是SVD计算的R, t,可以看到和随机生成的R, t是一致的。

image

image

奇异值分解正交矩阵UV的意义

我们使用去质心坐标q带入A, B点对的对应关系中

\[p_i-(Rp_i'+t)\\ =q_i+\bar p - [R(q_i' + \bar p' )+t] \\ =q-R q_i'+ \bar p - (R \bar p_i ' +t)\\ = q_i - Rq_i'=0 \]

可以发现在去质心坐标下有 \(q_i = R q_i'\),即A中的点 \(q_i\) 和B中对应的点 \(q_i'\)仅相差一个旋转矩阵,我们将求得的旋转矩阵展开

\[q_i = R q_i' = VU^T q_i' \Rightarrow V^Tq_i = U^Tq_i' \]

U和V分别都是正交矩阵\(UU^T=I\),我们将他们写成列向量形式,\(U=[U_x, U_y, U_z], V=[V_x, V_y, V_z]\),带入上式

\[[U_x, U_y, U_z]^T q_i = [V_x, V_y, V_z]^T q_i ' \Rightarrow \begin{bmatrix} U_x^T q_i \\ U_y^T q_i \\ U_z^T q_i \end{bmatrix} = \begin{bmatrix} V_x^T q_i' \\ V_y^T q_i' \\ V_z^T q_i' \end{bmatrix} \]

也就是说,在以U的三个列向量为基底的表示下的A中的点 \(q_i\) 与 以V的三个列向量为基底的表示下的B中的对应点 \(q_i'\) 的是相等的。

\(U^Tq_i\)\(V^Tq_i'\)表示的是同一个向量,这个向量在基U下坐标为\(q_i\),在基V下坐标为\(q_i'\)

求得的旋转矩阵\(R=VU^T\)其实就是进行了基的变换。

下图中粗一点的坐标轴是U的三个列向量构成的正交基(点集A的坐标系),细一点的坐标轴是V的三个列向量构成的正交基(点集B的坐标系)。

image

我们再将坐标系绘制在每个点集的质心处,得到下图。我们求解ICP得到的R, t就是这两个坐标系之间的姿态差异和位移。

image

看到这个坐标轴,读者可能会发现和主成分分析(Principal Component Analysis,PCA)有些类似,后续会用另一篇文章进行介绍。


参考文献

张贤达. 《矩阵分析与应用》第二版

高翔.《视觉SLAM十四讲》

K. S. ARUN, T. S. HUANG, AND S. D. BLOSTEIN. Least-Squares Fitting of Two 3-D Point Sets

posted @ 2023-11-02 20:29  cosmosociologist  阅读(80)  评论(0)    收藏  举报