1 基本实现
数据点云配准,最经典的方法就是ICP迭代最近点法。
- 最近点:欧几里得意义上距离最近的点。
- 迭代:迭代目标是通过不断更新运动参数,使得两个点云的重叠部分充分吻合。
ICP的求解分为两种方式:
- 利用线性代数求解(SVD),在给定了匹配的情况下,最小二乘问题实际上具有解析解。
- 利用非线性优化方式求解,类似于BA方法,适用于匹配未知的情况。
2 SVD方法求解
算法推导如下:
首先将点云文件进行粗匹配,如ORB特征点匹配。
从点集$P={\overrightarrow{p_1}, \overrightarrow{p_2}, …, \overrightarrow{p_n}}$中随机选取指定数量的点$\{\overrightarrow{p_t}\}$作为参考点,参考点的数量决定了ICP算法的计算效率和配准精度。
在另一个点集$Q={\overrightarrow{q_1}, \overrightarrow{q_2}, …, \overrightarrow{q_m}}$是待匹配的点
query points
,那么想要找到一个欧式变换$R, t$,使得$\forall i, p_i = Rq_i + t$。求解欧式变换$T^k$,使得$E^k=\Sigma| \overrightarrow{p_t} - T^k \overrightarrow{q_t}|^2$最小化。 将空间变换分解为旋转和平移两部分,首先定义两个点云的质心:
于是有目标函数:
对目标函数展开,而且已知旋转矩阵是正交阵,$R^TR=I$,所以目标函数的前两项都与$R$无关:
只有最后一项与$R$有关,于是得到关于$R$的目标函数:
然后通过SVD奇异值分解求解上述问题的最优$R$,首先定义$W = \sum_1^n pq^T$,当$W$满秩时:
然后间接得到平移$t$:
代码实现如下:
1 | void pose_estimation_3d3d( |
3 非线性优化方法
另一种方式是通过迭代的方式来寻找最优值,误差项的表示与上一节相同,用李代数来表达位姿,旋转和平移不用再解耦表示,目标函数为:
单个误差项关于位姿的导数可以使用李代数扰动模型来描述:
其中$p_i$作为参考点,对扰动的导数为0,因此:
将最小二乘问题进行图描述:优化变量为李代数表达的位姿$\xi$,因此图中只有一个节点,误差项为一元边(从当前节点指向当前节点),对误差项做线性展开:
其中的雅可比矩阵也就是上面说的,单个误差项关于位姿的一阶导数。
4算法优化
- 删除点云数据采集中产生的噪声及异常值。
- 查找最近点的过程采用KD-Tree数据结构,减少时间复杂度。