NICP算法介绍

NICP算法介绍

算法提出原文:NICP-Dense Normal Based Point Cloud Registration (from IEEE)

NICP是基于ICP算法的,由于ICP算法再点云的匹配关系上,是计算同一坐标系下的两帧点云上的点的距离最小作为比配点,这样的计算得到匹配关系,经常是错误的,会出现将不同位置(不同物体或者不同物体部分的扫描点)点进行匹配的情况,从而陷入局部最优。

激光雷达是将激光发射到环境表面,通过计算反射激光及发出激光的时间差得到机器人到环境表面的距离。因为可以通过点云得到环境表面的一些信息,比如是墙,还是弯曲的物体表面。通过对比点所在面的法向量,以及该点处的表面曲率,可以很大程度去筛除掉错误的点云匹配关系。

NICP在点云匹配上,除了约束点间的距离,另外加入了法向量及点云所在曲面的曲率的约束。

NICP迭代算法是基于ICP的,就是交叉迭代,即点云匹配与运动估计交叉迭代优化。如下图:
在这里插入图片描述

NICP的一次迭代计算主要包括:

1. 3D点云的位置p解算。

使用深度相机,得到环境的深度图,即每个点对应向量(u v d)。(u, v)点在图像中的像素坐标,d为点的深度信息。

使用激光雷达得到环境的点云分布情况,每个点对应向量(θ φ d),激光雷达的FOV指的雷达发射的激光能够覆盖环境的水平和竖直方向的角度。θ代表点相对于雷达的水平角度(方位角),φ表示点相对于雷达的竖直角度(高度角),即雷达在(θ φ)方向扫描到点,距离为d。

但是无论是深度图像表示(u v d),还是雷达扫描数据表示(θ φ d),都不是点相对于机器人的位姿坐标向量,我们统称为测量值,因此需要将这些测量值中,恢复点云的坐标表示。

文中用来表示点的位姿坐标到测量值得变换,用来表示点的测量值到位姿坐标得变换。

2. 提取点所在环境表面处的特征(面的法向量及曲率)

通过点云计算处各点所在面的曲率及法向(面在该点处的曲率和法向量)。


文中有公式应该是有误解的地方:在计算协方差时矩阵时表述有**,如下:
在这里插入图片描述
应为:
在这里插入图片描述

以下为纠正解释:

如果采用方差(不是协方差)来计算各点处点云分布的离散情况,比如,一堵墙,这堵墙上扫描得到的点云只在这个墙所代表的平面上对应的两个轴方向上协方差比较大。而与墙垂直的方向轴上的协方差比较小。如下图所示,该簇点云在x,y轴上的协方差比较大,z轴上较小。
在这里插入图片描述
采用方差只能判定出点云集在x,y,z三轴上的扩散程度,不能得到曲面的法向量。因为实际曲面不是都是墙面那样的平面。因此文中采用协方差来计算曲率及法向量,采用协方差矩阵能够表示点集各轴之间的相关性,即通过计算协方差矩阵的特征值及对应的特征向量,则利用3个特征向量组成的坐标系可以更加清楚的描述点云集特征,最小特征值对应的特征向量,则就表示曲面的法向量。如下图所示。
在这里插入图片描述
在这里插入图片描述
以上图片来自LOAM论文和程序代码的解读
设,x,y为三维向量, x = [ x 1 x 2 x 3 ] T x=\left[\begin{matrix}x_1&x_2&x_3\\\end{matrix}\right]^T x=[x1x2x3]T, 其中心向量为 c = [ c 1 c 2 c 3 ] T c=\left[\begin{matrix}c_1&c_2&c_3\\\end{matrix}\right]^T c=[c1c2c3]T
令:
x c = x − c = [ x c 1 x c 2 x c 3 ] T = [ x 1 − c 1 x 2 − c 2 x 3 − c 3 ] T x_c=x-c=\left[\begin{matrix}x_{c1}&x_{c2}&x_{c3}\\\end{matrix}\right]^T=\left[\begin{matrix}x_1-c_1&x_2-c_2&x_3-c_3\\\end{matrix}\right]^T xc=xc=[xc1xc2xc3]T=[x1c1x2c2x3c3]T
x的方差: x c T x c = [ x c 1 2 x c 2 2 x c 3 2 ] T x_c^Tx_c=\left[\begin{matrix}{x_{c1}}^2&{x_{c2}}^2&{x_{c3}}^2\\\end{matrix}\right]^T xcTxc=[xc12xc22xc32]T
x与y协方差: x y T = [ x 1 y 1 x 1 y 2 x 1 y 3 x 2 y 1 x 2 y 2 x 2 y 3 x 3 y 1 x 3 y 2 x 3 y 3 ] xy^T=\left[\begin{matrix}x_1y_1&x_1y_2&x_1y_3\\x_2y_1&x_2y_2&x_2y_3\\x_3y_1&x_3y_2&x_3y_3\\\end{matrix}\right] xyT=x1y1x2y1x3y1x1y2x2y2x3y2x1y3x2y3x3y3
x自身协方差: x c x c T x_cx_c^T xcxcT


文中协方差矩阵计算公式如下:
1)计算以点pi为中心的球域中所有点的重心:
在这里插入图片描述
2)计算该球域点集的协方差矩阵:

其中 V i V_i Vi为以点pi为中心的球域中所有点的集合.

协方差矩阵满足:
在这里插入图片描述
其中:
λ 1 , λ 2 , λ 3 \lambda_1, \lambda_2, \lambda_3 λ1,λ2,λ3按照升序排列,即 λ 1 < λ 2 < λ 3 \lambda_1<\lambda_2<\lambda_3 λ1<λ2<λ3
λ 1 , λ 2 , λ 3 \lambda_1, \lambda_2, \lambda_3 λ1,λ2,λ3对应的特征向量为 n 1 , n 2 , n 3 n_1, n_2, n_3 n1,n2,n3
λ 1 < λ 2 < λ 3 \lambda_1<\lambda_2<\lambda_3 λ1<λ2<λ3表示该点云在 n 1 n_1 n1方向上比较集中, n 2 , n 3 n_2, n_3 n2,n3上相对发散。

得:pi点处曲面法向量为,曲面的曲率可以表示为:
在这里插入图片描述

3. 点云匹配计算

以下几种情况,删除匹配关系:

1) 如果没有well define的法向量;
2) 两点间的距离大于阈值:
在这里插入图片描述
3) 两点处所在面的曲率之差距大于阈值:
在这里插入图片描述
4)两点处所在面的的法向量角度之差大于阈值:

向量点乘值越大,表明两个向量的夹角越小, a ∙   b = ∣ a ∣ ∣ b ∣ c o s θ a\bullet\ b=\left|a\right|\left|b\right|cos\theta a b=abcosθ, θ \theta θ为两向量夹角。

相比ICP的距离最小匹配,增加了对点所在曲面的曲率及法向量的约束,筛除更多的错误匹配点。

4. 运动估计

相比ICP的约束:
在这里插入图片描述
NICP的运动估计也加入了曲面法向量的约束。

令:⊕用来表示位姿+法向量的坐标变换过程,r代表原帧,c代表匹配帧。
在这里插入图片描述
在这里插入图片描述
得误差向量:
在这里插入图片描述
定义二乘正定形式:(相当于单维最小二乘法):
在这里插入图片描述
其中, Ω ~ i j \tilde \Omega_{ij} Ω~ij是6*6得信息矩阵,相当于优化中得惩罚性,通过它可以调整我们对不同元素偏差的重视程度。

论文中使用阻尼高斯牛顿来误差完成迭代最小化:
迭代步: T ← Δ T T\leftarrow \Delta T TΔT T T T

Δ T \Delta T ΔT求解:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其中:H为hessian阵,高斯牛顿法采用e函数的jacobine矩阵拟合H阵,详细解释见后端优化介绍内容。加 λ I \lambda I λI的并不是前边的特征根,是hessian的补偿项,保证hessian阵的正定性,因为求 Δ T \Delta T ΔT要对H求逆,因此H不能等于0。

J i j J_{ij} Jij就是 e e e函数的jacobine阵。

[ p ] X [p]_X [p]X是向量的叉乘阵,对应高翔博士说的符号∧,就是通过自我叉乘得到一个反对称矩阵,对应如下:
在这里插入图片描述

  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
NICP(Normal Distributions Transform Iterative Closest Point)算法是一种基于正态分布变换(NDT)的迭代最近点算法(ICP)的改进。其主要思想是使用NDT将点云表达为高斯混合模型,从而提高匹配的鲁棒性。 以下是MATLAB实现NICP算法的基本步骤: 1. 读取两个点云P和Q,并将它们转换为NDT表示形式。 2. 初始化变换矩阵T为单位矩阵。 3. 通过计算点云P和变换后的点云Q'之间的最近点对,计算初始误差。 4. 重复以下步骤直到收敛: - 计算点云P和变换后的点云Q'之间的最近点对。 - 基于最近点对计算出变换矩阵T。 - 将点云Q转换为T变换后的点云Q'。 - 计算误差并检查是否收敛。 以下是MATLAB代码示例: ``` % 读取点云 P = pcread('pointcloud1.pcd'); Q = pcread('pointcloud2.pcd'); % 将点云转换为NDT表示形式 ndt_P = pointCloud(P.Location); ndt_Q = pointCloud(Q.Location); % 初始化变换矩阵为单位矩阵 T = eye(4); % 设置迭代次数和误差阈值 max_iter = 100; error_threshold = 0.001; % 迭代计算 for i = 1:max_iter % 计算最近点对 [indices, distances] = findNearestNeighbors(ndt_Q, ndt_P.Location, 1); nearest_P = ndt_P.Location(indices,:); nearest_Q = ndt_Q.Location; % 计算变换矩阵 T = icp_transform(nearest_P, nearest_Q); % 将点云Q转换为T变换后的点云Q' ndt_Q = pctransform(ndt_Q, affine3d(T)); % 计算误差并检查是否收敛 error = sum(distances.^2) / length(distances); if error < error_threshold break; end end % 输出变换矩阵 disp(T); ``` 其中,icp_transform是自定义函数,用于计算变换矩阵。具体实现可以参考ICP算法,这里不再赘述。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值