本文介绍了用于深度融合管道(如 KinectFusion)的 ICP 算法。
ICP 的目标是对齐两个点云,一个是旧点云(三维模型中的现有点和法线),另一个是新点云(新点和法线,即我们要整合到现有模型中的点和法线)。ICP 返回这两个点云之间的旋转和平移变换。
迭代最近点(ICP)最小化目标函数,即两个点云中相应点之间的点到平面距离(PPD):
E = ∑ i ∣ ∣ p p d ( p i , q i , n i ) ∣ ∣ 2 → 0 E=\sum{_i||ppd\left( p_i,q_i,n_i \right) ||_2\rightarrow 0} E=∑i∣∣ppd(pi,qi,ni)∣∣2→0
什么是 ppd(p, q, n)?
具体来说,对于每个对应点 P 和 Q,它是点 P 到由点 Q 和位于点 Q 上的法线 N 所决定的平面的距离。
p - 新点云中的第 i 个点
q - 旧点云中的第 i 个点
n - 旧点云中 q 点的法线
因此, ppd(…) 可以表示为(p 和 q 之间的差值)和(n)的点积:
d
o
t
(
T
p
2
q
(
p
)
−
q
,
n
)
=
d
o
t
(
(
R
⋅
p
+
t
)
−
q
,
n
)
=
[
(
R
⋅
p
+
t
)
−
q
]
T
⋅
n
dot\left( T_{p2q}\left( p \right) -q,n \right) =dot\left( \left( R\cdot p+t \right) -q,n \right) =\left[ \left( R\cdot p+t \right) -q \right] ^T\cdot n
dot(Tp2q(p)−q,n)=dot((R⋅p+t)−q,n)=[(R⋅p+t)−q]T⋅n
T§ 是点 p 的刚性变换:
T
p
2
q
(
p
)
=
(
R
⋅
p
+
t
)
T_{p2q}\left( p \right) =\left( R\cdot p+t \right)
Tp2q(p)=(R⋅p+t)
T 是我们通过 ICP 搜索的变换,其目的是使每个点 p 与对应点 q 的点到平面距离更近。
如何最小化目标函数?
我们使用高斯-牛顿法进行函数最小化。
在高斯-牛顿法中,我们沿着函数 E 的下降方向,即梯度方向,通过改变 R 和 t 来完成连续步骤:
- 在每一步中,我们将函数 E 线性近似为其当前值加上雅各布矩阵乘以 delta x,后者是由 delta R 和 delta t 向量串联而成。
- 我们通过求解方程 E_approx(delta_x) = 0 来找到 delta R 和 delta t。
- 我们将 delta R 和 delta t 应用于当前的 Rt 变换,然后进行下一次迭代
如何对 E 进行线性化?
让我们在无限小邻域内对其进行近似。
下面是我们要通过改变 R 和 t 使其最小化的公式:
E
=
∑
∣
∣
[
(
R
⋅
p
+
t
)
−
q
]
T
⋅
n
∣
∣
2
E=\sum{||\left[ \left( R\cdot p+t \right) -q \right] ^T\cdot n||_2}
E=∑∣∣[(R⋅p+t)−q]T⋅n∣∣2
虽然点到平面的距离与 R 和 t 都是线性关系,但旋转空间本身并不是线性的。从 R 是如何从旋转角度生成的就可以看出这一点:
R
=
R
z
(
γ
)
R
y
(
β
)
R
x
(
α
)
=
[
cos
(
γ
)
−
sin
(
γ
)
0
sin
(
γ
)
cos
(
γ
)
0
0
0
1
]
[
cos
(
β
)
0
sin
(
β
)
0
1
0
−
sin
(
β
)
0
cos
(
β
)
]
[
1
0
0
0
cos
(
α
)
−
sin
(
α
)
0
sin
(
α
)
cos
(
α
)
]
R=R_z\left( \gamma \right) R_y\left( \beta \right) R_x\left( \alpha \right) =\left[ \begin{matrix} \cos \left( \gamma \right)& -\sin \left( \gamma \right)& 0\\ \sin \left( \gamma \right)& \cos \left( \gamma \right)& 0\\ 0& 0& 1\\ \end{matrix} \right] \left[ \begin{matrix} \cos \left( \beta \right)& 0& \sin \left( \beta \right)\\ 0& 1& 0\\ -\sin \left( \beta \right)& 0& \cos \left( \beta \right)\\ \end{matrix} \right] \left[ \begin{matrix} 1& 0& 0\\ 0& \cos \left( \alpha \right)& -\sin \left( \alpha \right)\\ 0& \sin \left( \alpha \right)& \cos \left( \alpha \right)\\ \end{matrix} \right]
R=Rz(γ)Ry(β)Rx(α)=
cos(γ)sin(γ)0−sin(γ)cos(γ)0001
cos(β)0−sin(β)010sin(β)0cos(β)
1000cos(α)sin(α)0−sin(α)cos(α)
但由于我们有无限小的旋转,R 可以用下面的形式近似表示:
R
=
I
+
A
d
θ
R=I+Ad\theta
R=I+Adθ
其中 I - 单位矩阵,A - 三维特殊正交群 so(3) 的成员。
将所有 sin(t) 和 cos(t) 项逼近其 t -> 0 时的极限,可以得到以下表示:
R
=
I
+
[
0
−
γ
β
γ
0
−
α
−
β
α
0
]
=
I
+
s
k
e
w
(
[
α
β
γ
]
T
)
=
I
+
s
k
e
w
(
R
s
h
i
f
t
)
R=I+\left[ \begin{matrix} 0& -\gamma& \beta\\ \gamma& 0& -\alpha\\ -\beta& \alpha& 0\\ \end{matrix} \right] =I+skew\left( \left[ \begin{matrix} \alpha& \beta& \gamma\\ \end{matrix} \right] ^T \right) =I+skew\left( R_{shift} \right)
R=I+
0γ−β−γ0αβ−α0
=I+skew([αβγ]T)=I+skew(Rshift)
将 R 的近似值代入 E 的表达式,就得到了:
E
a
p
p
r
o
x
=
∑
∣
∣
[
(
I
+
s
k
e
w
(
R
s
h
i
f
t
)
)
⋅
p
+
t
−
q
]
T
⋅
n
∣
∣
2
E_{approx}=\sum{||\left[ \left( I+skew\left( R_{shift} \right) \right) \cdot p+t-q \right] ^T\cdot n||_2}
Eapprox=∑∣∣[(I+skew(Rshift))⋅p+t−q]T⋅n∣∣2
E
a
p
p
r
o
x
=
∑
∣
∣
[
I
⋅
p
+
s
k
e
w
(
R
s
h
i
f
t
)
⋅
p
+
t
−
q
]
T
⋅
n
∣
∣
2
E_{approx}=\sum{||\left[ I\cdot p+skew\left( R_{shift} \right) \cdot p+t-q \right] ^T\cdot n||_2}
Eapprox=∑∣∣[I⋅p+skew(Rshift)⋅p+t−q]T⋅n∣∣2
E
a
p
p
r
o
x
=
∑
∣
∣
[
s
k
e
w
(
R
s
h
i
f
t
)
⋅
p
+
t
+
p
−
q
]
T
⋅
n
∣
∣
2
E_{approx}=\sum{||\left[ skew\left( R_{shift} \right) \cdot p+t+p-q \right] ^T\cdot n||_2}
Eapprox=∑∣∣[skew(Rshift)⋅p+t+p−q]T⋅n∣∣2
让我们引入一个近似变换移动的函数 f:
f
(
x
,
p
)
=
s
k
e
w
(
R
s
h
i
f
t
)
⋅
p
+
t
f\left( x,p \right) =skew\left( R_{shift} \right) \cdot p+t
f(x,p)=skew(Rshift)⋅p+t
E
a
p
p
r
o
x
=
∑
∣
∣
[
f
(
x
,
p
)
+
p
−
q
]
T
⋅
n
∣
∣
2
E_{approx}=\sum{||\left[ f\left( x,p \right) +p-q \right] ^T\cdot n||_2}
Eapprox=∑∣∣[f(x,p)+p−q]T⋅n∣∣2
如何最小化 E_approx?
当 E_approx 的差值(即参数增加的导数)为零时,E_approx 就是最小的:
d
(
E
a
p
p
r
o
x
)
=
∑
i
d
(
∣
∣
p
p
d
(
T
a
p
p
r
o
x
(
p
i
)
,
q
i
,
n
i
)
∣
∣
2
)
d\left( E_{approx} \right) =\sum{_id\left( ||ppd\left( T_{approx}\left( p_i \right) ,q_i,n_i \right) ||_2 \right)}
d(Eapprox)=∑id(∣∣ppd(Tapprox(pi),qi,ni)∣∣2)
∑
i
d
(
p
p
d
(
T
a
p
p
r
o
x
(
p
i
)
,
q
i
,
n
i
)
2
)
=
∑
i
2
⋅
p
p
d
(
.
.
.
)
⋅
d
(
p
p
d
(
T
a
p
p
r
o
x
(
p
i
)
,
q
i
,
n
i
)
)
\sum{_id\left( ppd\left( T_{approx}\left( p_i \right) ,q_i,n_i \right) ^2 \right) =\sum{_i2\cdot ppd\left( ... \right) \cdot d\left( ppd\left( T_{approx}\left( p_i \right) ,q_i,n_i \right) \right)}}
∑id(ppd(Tapprox(pi),qi,ni)2)=∑i2⋅ppd(...)⋅d(ppd(Tapprox(pi),qi,ni))
让我们微分一下 ppd:
d
(
p
p
d
(
T
a
p
p
r
o
x
(
p
i
)
,
q
i
,
n
i
)
)
=
d
(
[
f
(
x
,
p
i
)
+
p
i
−
q
i
]
T
⋅
n
i
)
=
d
f
(
x
,
p
i
)
T
⋅
n
i
=
d
x
T
f
′
(
x
,
p
i
)
T
⋅
n
i
d\left( ppd\left( T_{approx}\left( p_i \right) ,q_i,n_i \right) \right) =d\left( \left[ f\left( x,p_i \right) +p_i-q_i \right] ^T\cdot n_i \right) =df\left( x,p_i \right) ^T\cdot n_i=dx^Tf'\left( x,p_i \right) ^T\cdot n_i
d(ppd(Tapprox(pi),qi,ni))=d([f(x,pi)+pi−qi]T⋅ni)=df(x,pi)T⋅ni=dxTf′(x,pi)T⋅ni
下面是我们从向量 x 中得到的所有变量 x_j 的结果:
∂
E
∂
x
j
=
∑
[
2
⋅
(
f
(
x
,
p
)
+
p
−
q
)
T
⋅
n
]
⋅
[
f
j
′
(
x
,
p
)
T
⋅
n
]
=
0
\frac{\partial E}{\partial x_j}=\sum{\left[ 2\cdot \left( f\left( x,p \right) +p-q \right) ^T\cdot n \right] \cdot \left[ f_j'\left( x,p \right) ^T\cdot n \right] =0}
∂xj∂E=∑[2⋅(f(x,p)+p−q)T⋅n]⋅[fj′(x,p)T⋅n]=0
∑
[
2
⋅
n
T
⋅
(
f
(
x
,
p
)
+
p
−
q
)
T
]
⋅
[
n
T
⋅
f
′
(
x
,
p
)
]
=
0
\sum{\left[ 2\cdot n^T\cdot \left( f\left( x,p \right) +p-q \right) ^T \right] \cdot \left[ n^T\cdot f'\left( x,p \right) \right] =0}
∑[2⋅nT⋅(f(x,p)+p−q)T]⋅[nT⋅f′(x,p)]=0
让新变量:
Δ
p
=
p
−
q
\varDelta p=p-q
Δp=p−q
∑
[
2
⋅
n
T
⋅
(
f
(
x
,
p
)
+
Δ
p
)
T
]
⋅
[
n
T
⋅
f
′
(
x
,
p
)
]
=
0
\sum{\left[ 2\cdot n^T\cdot \left( f\left( x,p \right) +\varDelta p \right) ^T \right] \cdot \left[ n^T\cdot f'\left( x,p \right) \right] =0}
∑[2⋅nT⋅(f(x,p)+Δp)T]⋅[nT⋅f′(x,p)]=0
∑
[
(
f
(
x
,
p
)
+
Δ
p
)
T
⋅
(
n
⋅
n
T
)
]
⋅
f
′
(
x
,
p
)
=
0
\sum{\left[ \left( f\left( x,p \right) +\varDelta p \right) ^T\cdot \left( n·n^T \right) \right] \cdot f'\left( x,p \right) =0}
∑[(f(x,p)+Δp)T⋅(n⋅nT)]⋅f′(x,p)=0
∑
f
′
(
x
,
p
)
⋅
[
n
⋅
n
T
]
⋅
(
f
(
x
,
p
)
+
Δ
p
)
T
=
0
\sum{f'\left( x,p \right) \cdot \left[ n·n^T \right] \cdot \left( f\left( x,p \right) +\varDelta p \right) ^T=0}
∑f′(x,p)⋅[n⋅nT]⋅(f(x,p)+Δp)T=0
f(x, p) 可以表示为矩阵与向量相乘。要证明这一点,我们必须记住
c
r
o
s
s
(
a
,
b
)
=
s
k
e
w
(
a
)
⋅
b
=
s
k
e
w
(
b
)
T
⋅
a
cross\left( a,b \right) =skew\left( a \right) ·b=skew\left( b \right) ^T\cdot a
cross(a,b)=skew(a)⋅b=skew(b)T⋅a
f
(
x
,
p
)
=
s
k
e
w
(
R
s
h
i
f
t
)
⋅
p
+
t
s
h
i
f
t
=
s
k
e
w
(
p
)
T
R
s
h
i
f
t
+
t
s
h
i
f
t
f\left( x,p \right) =skew\left( R_{shift} \right) \cdot p+t_{shift}=skew\left( p \right) ^TR_{shift}+t_{shift}
f(x,p)=skew(Rshift)⋅p+tshift=skew(p)TRshift+tshift
f
(
x
,
p
)
=
[
s
k
e
w
(
p
)
T
I
3
×
3
]
⋅
[
Δ
R
Δ
t
]
T
=
G
(
p
)
⋅
x
f\left( x,p \right) =\left[ skew\left( p \right) ^T\ \ I_{3\times 3} \right] \cdot \left[ \varDelta R\ \ \varDelta t \right] ^T=G\left( p \right) \cdot x
f(x,p)=[skew(p)T I3×3]⋅[ΔR Δt]T=G(p)⋅x
引入 G§ 是为了简化计算。
因为
d
f
(
x
,
p
)
=
G
(
p
)
⋅
d
x
=
f
′
(
x
,
p
)
⋅
d
x
df\left( x,p \right) =G\left( p \right) \cdot dx=f'\left( x,p \right) \cdot dx
df(x,p)=G(p)⋅dx=f′(x,p)⋅dx
我们得到:
f
′
(
x
,
p
)
=
G
(
p
)
f'\left( x,p \right) =G\left( p \right)
f′(x,p)=G(p)
∑
f
′
(
x
,
p
)
T
⋅
[
n
⋅
n
T
]
⋅
[
f
(
x
,
p
)
]
=
∑
f
′
(
x
,
p
)
T
⋅
[
n
⋅
n
T
]
⋅
[
−
Δ
p
]
\sum{f'\left( x,p \right) ^T\cdot \left[ n·n^T \right] \cdot \left[ f\left( x,p \right) \right] =}\sum{f'\left( x,p \right) ^T\cdot \left[ n·n^T \right] \cdot \left[ -\varDelta p \right]}
∑f′(x,p)T⋅[n⋅nT]⋅[f(x,p)]=∑f′(x,p)T⋅[n⋅nT]⋅[−Δp]
∑
G
(
p
)
T
⋅
[
n
⋅
n
T
]
⋅
[
G
(
p
)
⋅
X
]
=
∑
G
(
p
)
T
⋅
[
n
⋅
n
T
]
⋅
[
−
Δ
p
]
\sum{G\left( p \right) ^T\cdot \left[ n·n^T \right] \cdot \left[ G\left( p \right) \cdot X \right] =}\sum{G\left( p \right) ^T\cdot \left[ n·n^T \right] \cdot \left[ -\varDelta p \right]}
∑G(p)T⋅[n⋅nT]⋅[G(p)⋅X]=∑G(p)T⋅[n⋅nT]⋅[−Δp]
让一个新值:
C
=
G
(
p
)
T
⋅
n
C=G\left( p \right) ^T\cdot n
C=G(p)T⋅n
C
T
=
(
G
(
p
)
T
⋅
n
)
T
=
n
T
⋅
G
(
p
)
C^T=\left( G\left( p \right) ^T\cdot n \right) ^T=n^T\cdot G\left( p \right)
CT=(G(p)T⋅n)T=nT⋅G(p)
让我们来替换一下:
∑
C
⋅
C
T
⋅
X
=
∑
C
⋅
n
T
⋅
[
−
Δ
p
]
\sum{C\cdot C^T\cdot X=\sum{C\cdot n^T\cdot \left[ -\varDelta p \right]}}
∑C⋅CT⋅X=∑C⋅nT⋅[−Δp]
∑
C
⋅
C
T
⋅
[
Δ
R
Δ
t
]
=
∑
C
⋅
n
T
⋅
[
−
Δ
p
]
\sum{C\cdot C^T\cdot \left[ \begin{array}{c} \varDelta R\\ \varDelta t\\ \end{array} \right] =\sum{C\cdot n^T\cdot \left[ -\varDelta p \right]}}
∑C⋅CT⋅[ΔRΔt]=∑C⋅nT⋅[−Δp]
通过求解这个方程,我们可以得到每次高斯-牛顿迭代的刚性变换位移。
如何应用变换位移?
我们从变换中生成旋转和平移矩阵,然后将当前姿态矩阵乘以我们得到的矩阵。
移位的平移部分会原封不动地加入到生成的矩阵中,而旋转部分的生成则比较麻烦。旋转偏移通过指数化从 so(3) 转换为 SO(3)。事实上,3 乘 1 的 rshift 向量代表旋转轴乘以旋转角度。我们使用罗德里格斯变换从中得到旋转矩阵。更多详情,请参阅维基页面。