ICP算法可以使用SVD或者非线性优化的方法进行求解。因为PCL源码中对ICP的求解就是使用SVD,所以这里对其进行一些探究。
1.公式推导
1.首先对第i i i 个点构建误差项:
e i = p i − ( R p i ′ + t )
e_{i}=p_{i}-\left(\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}+\boldsymbol{t}\right)
e i = p i − ( R p i ′ + t )
2.构建最小二乘问题:求得使得目标函数最小的未知量R , t R,t R , t
min R , t J = 1 2 ∑ i = 1 n ∥ ( p i − ( R p i ′ + t ) ) ∥ 2 2
\min _{\boldsymbol{R}, t} J=\frac{1}{2} \sum_{i=1}^{n}\left\|\left(\boldsymbol{p}_{i}-\left(\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}+\boldsymbol{t}\right)\right)\right\|_{2}^{2}
R , t min J = 2 1 i = 1 ∑ n ∥ ( p i − ( R p i ′ + t ) ) ∥ 2 2
接下来定义一些需要用的变量:
首先定义两组点云的质心:
p = 1 n ∑ i = 1 n ( p i ) , p ′ = 1 n ∑ i = 1 n ( p i ′ )
\boldsymbol{p}=\frac{1}{n} \sum_{i=1}^{n}\left(\boldsymbol{p}_{i}\right), \quad \boldsymbol{p}^{\prime}=\frac{1}{n} \sum_{i=1}^{n}\left(\boldsymbol{p}_{i}^{\prime}\right)
p = n 1 i = 1 ∑ n ( p i ) , p ′ = n 1 i = 1 ∑ n ( p i ′ )
4.在误差函数中添加质心,进行配平
1 2 ∑ i = 1 n ∥ p i − ( R p i ′ + t ) ∥ 2 = 1 2 ∑ i = 1 n ∥ p i − R p i ′ − t − p + R p ′ + p − R p ′ ∥ 2 = 1 2 ∑ i = 1 n ∥ ( p i − p − R ( p i ′ − p ′ ) ) + ( p − R p ′ − t ) ∥ 2 = 1 2 ∑ i = 1 n ( ∥ p i − p − R ( p i ′ − p ′ ) ∥ 2 + ∥ p − R p ′ − t ∥ 2 + 2 ( p i − p − R ( p i ′ − p ′ ) ) T ( p − R p ′ − t ) )
\begin{aligned}\frac{1}{2} \sum_{i=1}^{n}\left\|\boldsymbol{p}_{i}-\left(\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}+\boldsymbol{t}\right)\right\|^{2} &=\frac{1}{2} \sum_{i=1}^{n}\left\|\boldsymbol{p}_{i}-\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}-\boldsymbol{t}-\boldsymbol{p}+\boldsymbol{R} \boldsymbol{p}^{\prime}+\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}\right\|^{2} \\&=\frac{1}{2} \sum_{i=1}^{n}\left\|\left(\boldsymbol{p}_{i}-\boldsymbol{p}-\boldsymbol{R}\left(\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}\right)\right)+\left(\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}-\boldsymbol{t}\right)\right\|^{2} \\&=\frac{1}{2} \sum_{i=1}^{n}\left(\left\|\boldsymbol{p}_{i}-\boldsymbol{p}-\boldsymbol{R}\left(\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}\right)\right\|^{2}+\left\|\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}-\boldsymbol{t}\right\|^{2}+\right.\\&\left.2\left(\boldsymbol{p}_{i}-\boldsymbol{p}-\boldsymbol{R}\left(\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}\right)\right)^{T}\left(\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}-\boldsymbol{t}\right)\right)\end{aligned}
2 1 i = 1 ∑ n ∥ p i − ( R p i ′ + t ) ∥ 2 = 2 1 i = 1 ∑ n ∥ p i − R p i ′ − t − p + R p ′ + p − R p ′ ∥ 2 = 2 1 i = 1 ∑ n ∥ ( p i − p − R ( p i ′ − p ′ ) ) + ( p − R p ′ − t ) ∥ 2 = 2 1 i = 1 ∑ n ( ∥ p i − p − R ( p i ′ − p ′ ) ∥ 2 + ∥ p − R p ′ − t ∥ 2 + 2 ( p i − p − R ( p i ′ − p ′ ) ) T ( p − R p ′ − t ) )
注意到交叉项部分中,( p i − p − R ( p i ′ − p ′ ) ) \left(\boldsymbol{p}_{i}-\boldsymbol{p}-\boldsymbol{R}\left(\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}\right)\right) ( p i − p − R ( p i ′ − p ′ ) ) 在求和之后是为0的,因此目标优化函数可以进行化简,变成:
min R , t J = 1 2 ∑ i = 1 n ∥ p i − p − R ( p i ′ − p ′ ) ∥ 2 + ∥ p − R p ′ − t ∥ 2
\min _{\boldsymbol{R}, \boldsymbol{t}} J=\frac{1}{2} \sum_{i=1}^{n}\left\|\boldsymbol{p}_{i}-\boldsymbol{p}-\boldsymbol{R}\left(\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}\right)\right\|^{2}+\left\|\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}-\boldsymbol{t}\right\|^{2}
R , t min J = 2 1 i = 1 ∑ n ∥ p i − p − R ( p i ′ − p ′ ) ∥ 2 + ∥ p − R p ′ − t ∥ 2
5.仔细观察左右两项,我们发现左边只和旋转矩阵 R R R 相关,而右边既有 $R 也 有 也有 也 有 $t,但 只和质心相关。只要我们获得了 R R R ,令第二项为零就能得到 t t t 。于是,ICP 可以分为以下 三个步骤求解:
5.1 计算两组点的质心位置 p , p ′ p, p′ p , p ′ ,然后计算每个点的去质心座标:
q i = p i − p , q i ′ = p i ′ − p ′
\boldsymbol{q}_{i}=\boldsymbol{p}_{i}-\boldsymbol{p}, \quad \boldsymbol{q}_{i}^{\prime}=\boldsymbol{p}_{i}^{\prime}-\boldsymbol{p}^{\prime}
q i = p i − p , q i ′ = p i ′ − p ′
5.2 根据以下优化问题计算旋转矩阵:
R ∗ = arg min R 1 2 ∑ i = 1 n ∥ q i − R q i ′ ∥ 2
\boldsymbol{R}^{*}=\arg \min _{\boldsymbol{R}} \frac{1}{2} \sum_{i=1}^{n}\left\|\boldsymbol{q}_{i}-\boldsymbol{R} \boldsymbol{q}_{i}^{\prime}\right\|^{2}
R ∗ = arg R min 2 1 i = 1 ∑ n ∥ q i − R q i ′ ∥ 2
5.3 根据第二步的 R R R ,计算$ t$:
t ∗ = p − R p ′
\boldsymbol{t}^{*}=\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}
t ∗ = p − R p ′
6.根据以上推导,我们重点需要求出旋转量R R R ,求得之后代入自然可以获得t t t 。对公式(6)进行展开:
1 2 ∑ i = 1 n ∥ q i − R q i ′ ∥ 2 = 1 2 ∑ i = 1 n q i T q i + q i ′ T R T R q i ′ − 2 q i T R q i ′
\frac{1}{2} \sum_{i=1}^{n}\left\|\boldsymbol{q}_{i}-\boldsymbol{R} \boldsymbol{q}_{i}^{\prime}\right\|^{2}=\frac{1}{2} \sum_{i=1}^{n} \boldsymbol{q}_{i}^{T} \boldsymbol{q}_{i}+\boldsymbol{q}_{i}^{\prime T} \boldsymbol{R}^{T} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}-2 \boldsymbol{q}_{i}^{T} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}
2 1 i = 1 ∑ n ∥ q i − R q i ′ ∥ 2 = 2 1 i = 1 ∑ n q i T q i + q i ′ T R T R q i ′ − 2 q i T R q i ′
注意到第一项和 R R R 无关,第二项由于 R T R = I R^TR = I R T R = I ,亦与 R R R 无关。因此,实际上优化 目标函数变为:
∑ i = 1 n − q i T R q i ′ = ∑ i = 1 n − tr ( R q i ′ q i T ) = − tr ( R ∑ i = 1 n q i ′ q i T )
\sum_{i=1}^{n}-\boldsymbol{q}_{i}^{T} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}=\sum_{i=1}^{n}-\operatorname{tr}\left(\boldsymbol{R} \boldsymbol{q}_{i}^{\prime} \boldsymbol{q}_{i}^{T}\right)=-\operatorname{tr}\left(\boldsymbol{R} \sum_{i=1}^{n} \boldsymbol{q}_{i}^{\prime} \boldsymbol{q}_{i}^{T}\right)
i = 1 ∑ n − q i T R q i ′ = i = 1 ∑ n − t r ( R q i ′ q i T ) = − t r ( R i = 1 ∑ n q i ′ q i T )
其实就是3 ∗ 1 ∗ 1 ∗ 3 3*1 * 1*3 3 ∗ 1 ∗ 1 ∗ 3 的矩阵,自然只有对角线上的数据表示两个点之间的有效数据。
7.对这个优化函数的求解,则使用SVD来完成。定义矩阵:
W = ∑ i = 1 n q i q i ′ T
\boldsymbol{W}=\sum_{i=1}^{n} \boldsymbol{q}_{i} \boldsymbol{q}_{i}^{\prime T}
W = i = 1 ∑ n q i q i ′ T
W W W 是一个 3 × 3 的矩阵,对 W W W 进行 SVD 分解,得:
W = U Σ V T
\boldsymbol{W}=\boldsymbol{U} \boldsymbol{\Sigma} \boldsymbol{V}^{T}
W = U Σ V T
其中,Σ Σ Σ 为奇异值组成的对角矩阵,对角线元素从大到小排列,而 U U U 和 V V V 为正交矩 阵。当 W W W 满秩时,R R R 为:
R = U V T
\boldsymbol{R}=\boldsymbol{U} \boldsymbol{V}^{T}
R = U V T
求得结果后,根据公式(7)即可获得t t t 的结果。
2.PCL源码阅读
整个源码从align 函数开始,调用关系如上图所示。
需要注意的是,PCL中根据算法的分类,对所有的代码进行归类。比如pcl属于Registration类,那么所有的匹配算法都统一放在Registration文件夹下。
其中h文件是定义好的函数接口,一些简单的函数直接在里面通过内联函数的形式进行了完善。
impl(implement)文件夹下的hpp文件则是对h文件中定义的复杂文件的实现。
src文件夹则是一个空的.cpp文件,只包含了对应的头文件。个人理解主要是为了编译生成可调用的库文件。