前言
ICP的英文全称为Iterative Closest Point,即为迭代最近点。它在激光雷达应用频率很高,主要是在点云配准领域。ICP算法在是是视觉SLAM中应用也非常多,这个算法还是很重要。我们下面的讨论还是基于视觉SLAM,好了我们开始吧!
ICP算法流程
ICP算法顾名思义,就是找最近点。算法流程如下:
- step1:预处理点云
- step2:寻找对应点(最近点)
- step3:根据对应点,计算R和t
- step4:对点云进行转换,计算误差
- step5:不断迭代,直至误差小于某一个值
3D-3D: ICP
假设我们有一组配对好的3D点如下:
P
=
{
p
1
,
?
?
,
p
n
}
,
P
′
=
{
p
1
′
,
?
?
,
p
n
′
}
\boldsymbol{P}=\left\{\boldsymbol{p}_{1}, \cdots, \boldsymbol{p}_{n}\right\}, \quad \boldsymbol{P}^{\prime}=\left\{\boldsymbol{p}_{1}^{\prime}, \cdots, \boldsymbol{p}_{n}^{\prime}\right\}
P={p1?,?,pn?},P′={p1′?,?,pn′?}
现在我们想要找到一个欧式变换,使得
?
i
,
p
i
=
R
p
i
′
+
t
.
\forall i, \boldsymbol{p}_{i}=\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}+\boldsymbol{t}.
?i,pi?=Rpi′?+t.
上述的这个问题就可以使用ICP算法求解。这里主要需要注意下,如果仅考虑3D点之间的变换,此时和相机并没有关系。在RGB-D SLAM中用ICP问题指代匹配好的两组点间的运动估计问题(跟激光SLAM有区别,激光SLAM通常是未知的情况)。ICP求解主要是两种方式,一种是SVD,另一种是非线性优化方式求解。
SVD方法
根据前面描述的ICP问题,令第
i
i
i对点的误差为:
e
i
=
p
i
?
(
R
p
i
′
+
t
)
.
\boldsymbol{e}_{i}=\boldsymbol{p}_{i}-\left(\boldsymbol{R} \boldsymbol{p}_{i}^{\prime}+\boldsymbol{t}\right).
ei?=pi??(Rpi′?+t).
这里解释一下,我们用一个点
p
i
′
\boldsymbol{p}_{i}^{\prime}
pi′?(第二幅图中数据)来估算另一个点
p
i
\boldsymbol{p}_{i}
pi?时(在第一幅中数据,即为观测坐标),必然会产生误差。
我们构建最小二乘问题,求解使用平方和打到极小的
R
R
R和
t
t
t,则有
min
?
R
,
t
1
2
∑
i
=
1
n
∥
(
p
i
?
(
R
p
i
′
+
t
)
)
∥
2
2
.
\min _{\boldsymbol{R}, \boldsymbol{t}} \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,tmin?21?i=1∑n?∥(pi??(Rpi′?+t))∥22?.
定义图像1和图像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=n1?i=1∑n?(pi?),p′=n1?i=1∑n?(pi′?).
在误差函数做如下处理(去质心处理):
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)^{\mathrm{T}}\left(\boldsymbol{p}-\boldsymbol{R} \boldsymbol{p}^{\prime}-\boldsymbol{t}\right)\right) \end{aligned}
21?i=1∑n?∥pi??(Rpi?′+t)∥2===?21?i=1∑n?∥pi??Rpi?′?t?p+Rp′+p?Rp′∥221?i=1∑n?∥(pi??p?R(pi′??p′))+(p?Rp′?t)∥221?i=1∑n?(∥pi??p?R(pi′??p′)∥2+∥p?Rp′?t∥2+2(pi??p?R(pi?′?p′))T(p?Rp′?t))?
最终优化目标函数简化为
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}, 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,tmin?J=21?i=1∑n?∥pi??p?R(pi′??p′)∥2+∥p?Rp′?t∥2.
我们可以先求左边的第一项,我们记去质心坐标为:
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}.
qi?=pi??p,qi′?=pi′??p′.
由于左边第一项只和
R
R
R有关,因此我们先计算旋转矩阵
R
R
R,则
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?=argRmin?21?i=1∑n?∥qi??Rqi′?∥2
我们将
R
?
\boldsymbol{R}^{*}
R?进行展开,则为
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}\left(\boldsymbol{q}_{i}^{\mathrm{T}} \boldsymbol{q}_{i}+\boldsymbol{q}_{i}^{\prime \mathrm{T}} \boldsymbol{R}^{\mathrm{T}} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}-2 \boldsymbol{q}_{i}^{\mathrm{T}} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}\right)
21?i=1∑n?∥qi??Rqi′?∥2=21?i=1∑n?(qiT?qi?+qi′T?RTRqi′??2qiT?Rqi′?)
由于
R
T
R
=
I
\boldsymbol{R}^{\mathrm{T}} \boldsymbol{R}=\boldsymbol{I}
RTR=I,继续化简优化目标函数变为
∑
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}^{\mathrm{T}} \boldsymbol{R} \boldsymbol{q}_{i}^{\prime}=\sum_{i=1}^{n}-\operatorname{tr}\left(\boldsymbol{R} \boldsymbol{q}_{i}^{\prime} \boldsymbol{q}_{i}^{\mathrm{T}}\right)=-\operatorname{tr}\left(\boldsymbol{R} \sum_{i=1}^{n} \boldsymbol{q}_{i}^{\prime} \boldsymbol{q}_{i}^{\mathrm{T}}\right)
i=1∑n??qiT?Rqi′?=i=1∑n??tr(Rqi′?qiT?)=?tr(Ri=1∑n?qi′?qiT?)
为了解
R
R
R,定义矩阵:
W
=
∑
i
=
1
n
q
i
q
i
′
T
.
\boldsymbol{W}=\sum_{i=1}^{n} \boldsymbol{q}_{i} \boldsymbol{q}_{i}^{\prime \mathrm{T}}.
W=i=1∑n?qi?qi′T?.
使用SVD分解,使得
W
=
U
Σ
V
T
\boldsymbol{W}=\boldsymbol{U} \boldsymbol{\Sigma} \boldsymbol{V}^{\mathrm{T}}
W=UΣVT,当
W
\boldsymbol{W}
W满秩时,则
R
=
U
V
T
\boldsymbol{R}=\boldsymbol{U} \boldsymbol{V}^{\mathrm{T}}
R=UVT
解得
R
R
R以后,
t
t
t即为
t
?
=
p
?
R
p
′
t^{*}=p-R p^{\prime}
t?=p?Rp′
非线性优化方法
李代数表达位姿,迭代方式找到最优值。目标函数为:
min
?
ξ
=
1
2
∑
i
=
1
n
∥
(
p
i
?
exp
?
(
ξ
∧
)
p
i
′
)
∥
2
2
\min _{\boldsymbol{\xi}}=\frac{1}{2} \sum_{i=1}^{n}\left\|\left(\boldsymbol{p}_{i}-\exp \left(\boldsymbol{\xi}^{\wedge}\right) \boldsymbol{p}_{i}^{\prime}\right)\right\|_{2}^{2}
ξmin?=21?i=1∑n?∥∥?(pi??exp(ξ∧)pi′?)∥∥?22?
实践:求解ICP
SVD方法
void pose_estimation_3d3d(const vector<Point3f> &pts1, const vector<Point3f> &pts2, Mat &R, Mat &t)
{
Point3f p1, p2; // center of mass
int N = pts1.size();
for (int i = 0; i < N; i++) {
p1 += pts1[i];
p2 += pts2[i];
}
p1 = Point3f(Vec3f(p1) / N);
p2 = Point3f(Vec3f(p2) / N);
vector<Point3f> q1(N), q2(N); // remove the center
for (int i = 0; i < N; i++) {
q1[i] = pts1[i] - p1;
q2[i] = pts2[i] - p2;
}
// compute q1*q2^T
Eigen::Matrix3d W = Eigen::Matrix3d::Zero();
for (int i = 0; i < N; i++) {
W += Eigen::Vector3d(q1[i].x, q1[i].y, q1[i].z) * Eigen::Vector3d(q2[i].x, q2[i].y, q2[i].z).transpose();
}
cout << "W=" << W << endl;
// SVD on W
Eigen::JacobiSVD<Eigen::Matrix3d> svd(W, Eigen::ComputeFullU | Eigen::ComputeFullV);
Eigen::Matrix3d U = svd.matrixU();
Eigen::Matrix3d V = svd.matrixV();
cout << "U=" << U << endl;
cout << "V=" << V << endl;
Eigen::Matrix3d R_ = U * (V.transpose());
if (R_.determinant() < 0) {
R_ = -R_;
}
Eigen::Vector3d t_ = Eigen::Vector3d(p1.x, p1.y, p1.z) - R_ * Eigen::Vector3d(p2.x, p2.y, p2.z);
// convert to cv::Mat
R = (Mat_<double>(3, 3) <<
R_(0, 0), R_(0, 1), R_(0, 2),
R_(1, 0), R_(1, 1), R_(1, 2),
R_(2, 0), R_(2, 1), R_(2, 2)
);
t = (Mat_<double>(3, 1) << t_(0, 0), t_(1, 0), t_(2, 0));
}
|