前言
通常,使用RGB-D相机或是其他方法获取到物体的三维点云后,由于采集设备不同、拍摄视角不同等等因素的影响,即使是同一个物体所得到的点云也会有较大的差异,主要是旋转或者平移的变化。对于一组图像数据集中的两幅图像,需要通过寻找一种空间变换把一幅图像映射到另一幅图像,使得两图中对应于空间同一位置的点一一对应起来,从而达到信息融合的目的。所以,就需要对点云进行配准。
迭代最近点算法(ICP)是一种点云匹配算法。其思想是:通过旋转、平移使得两个点集之间的距离最小。ICP算法由Besl等人于1992年提出,文献可以参考:A Method for Registration of 3D Shapes,另外还可以参考:Least-Squares Fitting of Two 3-D Point Sets。前者使用的是四元数方法来求解旋转矩阵,而后者则是通过对协方差矩阵求解SVD来得到最终的旋转矩阵。流程大体上一致,后面就主要列出前者的流程。
ICP
1、四元数
我们可以使用四元数表示旋转关系: qR→=[q0q1q2q3]T q R → = [ q 0 q 1 q 2 q 3 ] T ,满足条件: q0≥0 q 0 ≥ 0 、 q20+q21+q22+q23=1 q 0 2 + q 1 2 + q 2 2 + q 3 2 = 1 。
由于点的坐标是用 [xyz]T [ x y z ] T 表示,如果要对其做某个旋转或者平移变换,无法也用四元数来表示,所以要通过下面的公式得到四元数所表示的旋转矩阵:
RqR→=⎡⎣⎢⎢q20+q21−q22−q232(q1q2+q2q3)2(q1q3−q0q22(q1q2−q2q3)q20−q21+q22−q232(q2q3+q0q1)2(q1q3+q0q2)2(q2q3−q0q1)q20−q21−q22+q23⎤⎦⎥⎥(1) (1) R q R → = [ q 0 2 + q 1 2 − q 2 2 − q 3 2 2 ( q 1 q 2 − q 2 q 3 ) 2 ( q 1 q 3 + q 0 q 2 ) 2 ( q 1 q 2 + q 2 q 3 ) q 0 2 − q 1 2 + q 2 2 − q 3 2 2 ( q 2 q 3 − q 0 q 1 ) 2 ( q 1 q 3 − q 0 q 2 2 ( q 2 q 3 + q 0 q 1 ) q 0 2 − q 1 2 − q 2 2 + q 3 2 ]
注:虽然四元数相对难理解一些,但是稍加对比就能发现,使用四元数来表示旋转关系能减少很多参数。迭代时可是要多次用到这个旋转关系的,可以节约不少计算量。这样,我们只需要在最后通过上式将四元数表示的旋转关系转换回旋转矩阵即可。
平移向量可以表示为:
T=[q4q5q6]T(2) (2) T = [ q 4 q 5 q 6 ] T
2、算法流程
1、假设待配准的点集为: P={pi→} P = { p i → } ;模板点集为: X={xi→} X = { x i → } 。
接下来要从带配准的点集 P P 中提取出与模板点集 X X 中的每个点最近的匹配点,度量方式采用欧式距离。对于模板点集 X X 中的每个点,求其到到点集 P P 中每个点的欧氏距离,取出欧氏距离最小的那个点,作为对应点放入新的对应点集 P′ P ′ 。为表述简洁,第2节开始后面提到的点集 P P 默认都是指对应点集 P′ P ′ 。
注:原论文中说这一步要保证两个点集 P P 和 X X 的点的个数相同: Nx=Np N x = N p ,实际使用中可以不必保证这一点。因为模板点集是固定的,我们所要做的只是计算模板点集中的 Np N p 个点对应点集 P P 中的点,即欧式距离最小的点,点集 P P 中的点的个数可以不等于 Np N p 。但是对应点集 P′ P ′ 的点与点集 X X 中的点一一对应,其点的个数肯定等于 Np N p 。而实际使用中,两个点集往往也是不相等的。
2、对于两个点集之间的度量,使用如下目标函数表示:
f(q⃗ )=1Np∑i=1Np||xi→−Rq⃗ pi→−T||2(3) (3) f ( q → ) = 1 N p ∑ i = 1 N p | | x i → − R q → p i → − T | | 2
其中,
q⃗ q → 表示四元数变量,
Rq⃗ R q → 为将四元数转换为旋转矩阵的形式,
T T 是前面定义过的平移矩阵;
xi→ x i → 表示模板点集
X X 中的某个点的坐标,
pi→ p i → 表示对应点集
P′ P ′ 中的对应点的坐标。
求解ICP的过程,就是求解上面这个目标函数最小值的过程:
minf(q⃗ ) min f ( q → ) 。每次迭代过程都求解能使得
f(q⃗ ) f ( q → ) 更小的
q⃗ q → ,迭代收敛后返回的
q⃗ q → 即为最终配准后的结果。
3、设点集 P P 和点集 X X 的中心点分别为 μp→ μ p → 和 μx→ μ x → :
⎧⎩⎨μp→=1Np∑Npi=1pi→μx→=1Np∑Npi=1xi→(4) (4) { μ p → = 1 N p ∑ i = 1 N p p i → μ x → = 1 N p ∑ i = 1 N p x i →
对点集
P P 和点集
X X 做去中心化处理后,求出其协方差矩阵:
Σpx=1Np∑i=1Np[(pi→−up→)(xi→−ux→)T]=1Np∑i=1Np(pi→xi→T)−μp→μx→T(5) (5) Σ p x = 1 N p ∑ i = 1 N p [ ( p i → − u p → ) ( x i → − u x → ) T ] = 1 N p ∑ i = 1 N p ( p i → x i → T ) − μ p → μ x → T
令对称矩阵:
Aij=(Σij−ΣTij)ij(6) (6) A i j = ( Σ i j − Σ i j T ) i j
由此得到列向量:
Δ=[A23A31A12]T(7) (7) Δ = [ A 23 A 31 A 12 ] T
利用该列向量构建
4×4 4 × 4 对称矩阵:
Q=[tr(Σpx)ΔΔTΣpx+ΣTpx−tr(Σpx)I3](8) (8) Q = [ t r ( Σ p x ) Δ T Δ Σ p x + Σ p x T − t r ( Σ p x ) I 3 ]
其中,
tr(Σpx) t r ( Σ p x ) 表示矩阵
Σpx Σ p x 的迹,即主对角线元素的总和,也即特征值之和。
I3 I 3 表示
3×3 3 × 3 的单位矩阵。
将式子7代入式子8中:
程序中直接套用上面这个公式即可。
4、对式子9中的矩阵 Q Q 作特征值分解,求得最大的特征值以及其对应的特征向量,那个特征向量就对应误差的平方和最小时的四元数。(这个我也不是很清楚,为什么这个特征向量就对应误差平方和最小时的四元数???)
q⃗ =[q0q1q2q3]T(9) (9) q → = [ q 0 q 1 q 2 q 3 ] T
使用上式的四元数套入公式1:
RqR→=⎡⎣⎢⎢q20+q21−q22−q232(q1q2+q2q3)2(q1q3−q0q22(q1q2−q2q3)q20−q21+q22−q232(q2q3+q0q1)2(q1q3+q0q2)2(q2q3−q0q1)q20−q21−q22+q23⎤⎦⎥⎥(1) (1) R q R → = [ q 0 2 + q 1 2 − q 2 2 − q 3 2 2 ( q 1 q 2 − q 2 q 3 ) 2 ( q 1 q 3 + q 0 q 2 ) 2 ( q 1 q 2 + q 2 q 3 ) q 0 2 − q 1 2 + q 2 2 − q 3 2 2 ( q 2 q 3 − q 0 q 1 ) 2 ( q 1 q 3 − q 0 q 2 2 ( q 2 q 3 + q 0 q 1 ) q 0 2 − q 1 2 − q 2 2 + q 3 2 ]
可以求得这次迭代的旋转矩阵。
旋转矩阵确定后,平移矩阵很容易确定了,就是两个点集中心做平移。
T=μx→−RqR→μp→ T = μ x → − R q R → μ p →
5、计算目标函数如下式,如果结果小于阈值则停止迭代,否则继续重复前面的步骤1-4;
f(q⃗ )=1Np∑i=1Np||xi→−Rq⃗ pi→−T||2(3) (3) f ( q → ) = 1 N p ∑ i = 1 N p | | x i → − R q → p i → − T | | 2
实验
实验的代码我会贴在文末,下面是实验结果。
点云配准前:
使用ICP算法配准后:
ICP最终得到旋转矩阵和误差:
代码
我已将代码上传到了github上,请自行下载。
https://github.com/ToughStoneX/3D_ICP
参考资料
1、https://blog.csdn.net/u013832676/article/details/44316107
2、https://blog.csdn.net/u011772859/article/details/44885675
3、https://wenku.baidu.com/view/08833045d15abe23482f4da4.html