点云配准ICP算法笔记

参考:【PCL】------ 点云配准ICP(Iterative Closest Point)算法_icp点云配准-CSDN博客

点云配准

计算出两个点云簇之间的变换矩阵,从而计算出位姿等信息,学习点云配准的目的是想要计算相邻两帧物体的点云之间的变换位姿,从而得到物体的运动信息。

ICP算法

ICP即 Iterative Closest Point 迭代最近点法,是一种经典的点云配准方法。ICP算法需要输入两个点云,一个是目标点云,另一个是源点云,输出的是从源点云到目标点云的位姿变换。目标点云 不会移动,而源点云则会在迭代的过程中不断接近目标点云,直到收敛。

但是ICP算法很容易陷入局部最优解,通常需要目标点云和源点云在配准前有比较高的重合率,因此在执行ICP之前通常会用其他方法进行一次粗配准,来获得比较好的初值,然后再使用ICP进行精配准。

原理推导

对于给定的点集 P = {P1, P2, P3, ... , Pn} 和 点云 Q = {qi, q2, q3, ... , qn}, 经典的ICP算法会对以下目标函数进行优化

该目标函数的含义也比较好理解,即找到一个刚体变换 < R, t > 使得源点云 P 和 目标点云 Q 的 差异尽可能的小,那么如何衡量这两个点云簇的差异呢?经典的ICP算法会遍历 < R, t > 变换后的源点云中的所有点 ,从目标点云中搜索出每一个的最近邻点,形成点对,计算点对距离的平方,并对所有点对的距离平方求和,最和最小则认为差异最小。

当匹配点对确定好之后,ICP的优化函数其实是一个凸函数,可以找到最优解,求解过程可以使用SVD分解,具体过程略

基于PCL的ICP代码详解

PCL点云库已经实现了多种点云配准算法,结合pcl,本次配准的主要目的是:

  1. 对PCL中ICP算法进行一些注解
  2. 创建可视化窗口,通过设置键盘回调函数,控制迭代过程,观察ICP算法的计算过程

PCL中的ICP算法是基于SVD(Singular Value Decomposition)实现的.

PCL中ICP的官方参考文档 http://pointclouds.org/docume...

ICP代码参数设置

使用pcl的ICP之前要设置几个参数

cpp 复制代码
//创建ICP的实例类
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
// 设置源点云
icp.setInputSource(cloud_sources);
// 设置目标点云
icp.setInputTarget(cloud_target);
// 设置对应点对之间的最大距离,影响结果的精度
icp.setMaxCorrespondenceDistance(100); 
// 设置两次变化矩阵之间的差值(一般设置为1e-10即可) 
icp.setTransformationEpsilon(1e-10); 
// 设置收敛条件是均方误差和小于阈值, 停止迭代
icp.setEuclideanFitnessEpsilon(0.001); 
// 设置最大迭代次数
icp.setMaximumIterations(100);   
icc.align(final);

完整代码

ICP变种之点线PL-ICP

参考:https://zhuanlan.zhihu.com/p/506823350#:~:text=CP%E7%AE%97%E6%B3%95.%20%E5%AF%B9%E4%BA%8Epo

代码:

上述介绍的ICP算法特指 点到点的ICP,即 point-to-point ICP,但是点到点的ICP算存在以下缺点:

  1. 依赖初始值,初始值不好时,迭代次数增加;
  2. 对于较大的初始误差,可能会出现错误的迭代结果;
  3. ICP是一阶收敛,收敛速度慢(为了弥补这一点,通常使用K-D树加快搜索);
  4. 存在离群点及噪声。

为此改善上述缺点,有研究者提出了PL-ICP,顾名思义,这种方式使用源点云到目标点云直线的距离度量来估计变换。主要区别在于误差函数的构建上。ICP是找最近邻的一点,以点与点之间的距离作为误差,而PLICP是找到最近邻的两点,两点连线,是以点到线的距离作为误差,实际上,后者的误差度量方式更符合结构化场景中的雷达点云的实际情况。因此具有更小的误差(图2)。然而,它对非常大的初始位移误差的鲁棒性较差,因此需要比较精确的初始值。
图2 点到线度量比普通 ICP 中使用的点到点度量更接近表面的距离

点到线的误差函数写为:

为目标点云中匹配到的最近两个点对应直线的法线。

ICP变种之点面ICP

相关推荐
人类恶.14 分钟前
C 语言学习笔记(数组)
c语言·笔记·学习
夏季疯17 分钟前
学习笔记:黑马程序员JavaWeb开发教程(2025.4.7)
java·笔记·学习
麟城Lincoln2 小时前
【Linux笔记】nfs网络文件系统与autofs(nfsdata、autofs、autofs.conf、auto.master)
linux·网络·笔记·nfs·autofs
田梓燊4 小时前
数学复习笔记 12
笔记·线性代数·机器学习
愚润求学4 小时前
【Linux】进程间通信(一):认识管道
linux·运维·服务器·开发语言·c++·笔记
霸王蟹4 小时前
React中useState中更新是同步的还是异步的?
前端·javascript·笔记·学习·react.js·前端框架
霸王蟹4 小时前
React Hooks 必须在组件最顶层调用的原因解析
前端·javascript·笔记·学习·react.js
珊瑚里的鱼4 小时前
【滑动窗口】LeetCode 1658题解 | 将 x 减到 0 的最小操作数
开发语言·c++·笔记·算法·leetcode·stl
请你喝好果汁6416 小时前
Jupyter Notebook 配置学习笔记
笔记·学习·jupyter
Lester_11019 小时前
嵌入式学习笔记 - STM32 ADC 模块工作模式总结
笔记·学习