作者:PCIPG-Jing | 来源:3DCV

1 什么是点云配准
点云配准指的是输入两幅点云 Ps (source) 和 Pt (target),输出一个变换矩阵T(即旋转R和平移t)使得 T(Ps)和Pt的重合程度尽可能高。我们可以把点云想象成由无数个三维点组成的云彩,而点云配准就是要把这些云彩按照它们实际的位置和姿态拼接在一起,就像把多个拼图拼接在一起,最终形成一个完整的三维模型。粗配准(Coarse Registration)在两幅点云之间的变换完全未知的情况下进行较为粗糙的配准,目的主要是为精配准提供较好的变换初值。精配准(Fine Registration)精配准是给定一个初始变换,进一步优化得到更精确的变换。粗配准和精配准流程如下图所示:
2 常见的配准算法
2.1 4PCS配准
1 原理
并非全共线的共面四点a,b,c,d,定义了两个独立的比率r1和r2,其在仿射变化中是不变且唯一的。现在给定一个具有n个点的点集Q,以及两个由点P得到的仿射不变的比率r1,r2,对每一对点q1,q2⊂ Q,计算他们的中间点:
若任意两对这样的点,一对由 r1计算得到的中间点和另一对由 r2计算得到的中间点在允许范围内一致,那么可以认为这两对点可能是 P中基础点的仿射对应点。将四点转化应用到全局点云转化,计算点云的匹配重叠度,若达到设置的阈值,则完成点云粗配准。
2 核心代码
pcl::registration::FPCSInitialAlignment<:pointxyz> fpcs;
fpcs.setInputSource(source_cloud); // 源点云
fpcs.setInputTarget(target_cloud); // 目标点云
fpcs.setApproxOverlap(0.7); // 设置源和目标之间的近似重叠度。
fpcs.setDelta(0.01); // 设置常数因子delta,用于对内部计算的参数进行加权。
fpcs.setNumberOfSamples(100); // 设置验证配准效果时要使用的采样点数量
2.2 K-4PCS配准
1 步骤
K-4PCS方法主要分为两个步骤:
(1)利用VoxelGrid滤波器对点云Q进行下采样,然后使用标准方法进行3D关键点检测。
(2)通过4PCS算法使用关键点集合而非原始点云进行数据的匹配,降低了搜索点集的规模,提高了运算效率。
2 核心代码
pcl::registration::KFPCSInitialAlignment<:pointxyz> kfpcs;
kfpcs.setInputSource(source); // 源点云
kfpcs.setInputTarget(target); // 目标点云
kfpcs.setApproxOverlap(0.7); // 源和目标之间的近似重叠。
kfpcs.setLambda(0.5); // 平移矩阵的加权系数。
kfpcs.setDelta(0.002, false); // 配准后源点云和目标点云之间的距离
kfpcs.setNumberOfThreads(6); // OpenMP多线程加速的线程数
kfpcs.setNumberOfSamples(200); // 配准时要使用的随机采样点数量
pcl::PointCloud<:pointxyz>::Ptr kpcs(new pcl::PointCloud<:pointxyz>);
kfpcs.align(*kpcs);
2.3 SAC-IA配准
1 步骤SAC-IA配准的实现流程:
①分别计算源点云和目标点云的FPFH特征描述子;
②基于FPFH特征描述子对两个点云中的点进行匹配;
③随机选择 n (n >= 3) 对匹配点;
④求解该匹配情况下的旋转与平移矩阵;
⑤计算此时对应的误差;重复步骤3-5,直到满足条件,将最小误差对应的旋转和位移作为最终结果。
2 核心代码
pcl::SampleConsensusInitialAlignment<:pointxyz> sac_ia;
sac_ia.setInputSource(source);
sac_ia.setSourceFeatures(source_fpfh);
sac_ia.setInputTarget(target);
sac_ia.setTargetFeatures(target_fpfh);
sac_ia.setMinSampleDistance(0.1);//设置样本之间的最小距离
sac_ia.setCorrespondenceRandomness(6); //在选择随机特征对应时,设置要使用的邻居的数量;
pointcloud::Ptr align(new pointcloud);
sac_ia.align(*align);
2.4 主成分分析法(PCA)配准
1 原理
主要利用点云数据的主轴方向进行配准。首先计算两组点云的协方差矩阵,根据协方差矩阵计算主要的特征分量,即点云数据的主轴方向,然后再通过主轴方向求出旋转矩阵,计算两组点云中心坐标的便移直接求出平移向量。
2 核心代码
void ComputeEigenVectorPCA(const pcl::PointCloud<:pointxyz>::Ptr& cloud, Eigen::Vector4f& pcaCentroid, Eigen::Matrix3f& eigenVectorsPCA)
{
pcl::compute3DCentroid(*cloud, pcaCentroid);
Eigen::Matrix3f covariance;
pcl::computeCovarianceMatrixNormalized(*cloud, pcaCentroid, covariance);
Eigen::SelfAdjointEigenSolver<:matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);
eigenVectorsPCA = eigen_solver.eigenvectors();
}
2.5 ICP配准
1 原理
ICP算法的核心是最小化一个目标函数,实际上就是所有对应点之间的欧式距离的平方和。
2 步骤
①寻找对应点:我们在有初值的情况下,假设用初始的变换矩阵对source cloud进行变换,将变换后的点云与target cloud进行比较,只要两个点云距离小于一定阈值,我们就认为这两个点就是对应点。
②R、T优化:有了对应点之后,我们就可以用对应点对旋转R与平移T进行估计。这里R和T中只有6个自由度,而我们的对应点数量是庞大的。因此,我们可以采用最小二乘等方法求解最优的旋转平移矩阵,一个数值优化问题。
③迭代:我们优化得到了一个新的R与T,导致了一些点转换后的位置发生变化,一些对应点也相应的发生了变化。因此,我们又回到了步骤②中的寻找对应点方法。②③步骤不停迭代进行,直到满足一些迭代终止条件,如R、T的变化量小于一定值,或者上述目标函数的变化小于一定值,或者对应点不再变化等。
3 核心代码
icp.setInputSource(source); // 源点云
icp.setInputTarget(target); // 目标点云
icp.setTransformationEpsilon(1e-10); // 为终止条件设置最小转换差异
icp.setMaxCorrespondenceDistance(1); // 设置对应点对之间的最大距离(此值对配准结果影响较大)。
icp.setEuclideanFitnessEpsilon(0.05); // 设置收敛条件是均方误差和小于阈值, 停止迭代;
icp.setMaximumIterations(35); // 最大迭代次数
pcl::PointCloud<:pointxyz>::Ptr icp_cloud(new pcl::PointCloud<:pointxyz>);
icp.align(*icp_cloud);
3 深度学习的配准算法
①PointNetLK (Deep ICP)
是基于 PointNet的改进版ICP算法。PointNet被用来提取点云的全局特征,然后使用牛顿法迭代近似相似性变换参数,并且使用这个过程中估计的点对映射来更新权重。
②Deep Closest Point (DCP)
基于深度神经网络的点云配准算法,它先通过PointNet提取特征,然后计算每个点在目标点云中的最近邻点,并计算这两个点之间的距离。之后,它将这些信息传递到一个形状编码器来学习在两个点云之间寻找最优配准关系,并输出变换矩阵使得两个点云重合。
③PRNet
PRNet是基于 PointNet++ 的点云配准算法。它的主要思想是将两个点云投射到一个球面上,然后计算在这个球面上的卷积特征。卷积完成后,PRNet使用粗配准阶段进行初始配准,再使用 RANSAC 进行细配准,最终输出配准矩阵。
④PPFNet
PPFNet是基于局部点对特征(PPF)的点云配准算法,使用神经网络学习点对之间的相对变换,并输出变换矩阵使得两个点云对齐。这个算法使用卷积神经网络对点云进行编码,并学习 PPF 匹配关系的特征,并使用训练过的网络对新的点云对进行配准。
4 参考资料
https://blog.csdn.net/qq_36686437/article/details/114160640
https://www.zhihu.com/tardis/bd/art/506823350?source_id=1001
—END—高效学习3D视觉三部曲
第一步 加入行业交流群,保持技术的先进性
目前工坊已经建立了3D视觉方向多个社群,包括SLAM、工业3D视觉、自动驾驶方向,细分群包括:[工业方向]三维点云、结构光、机械臂、缺陷检测、三维测量、TOF、相机标定、综合群;[SLAM方向]多传感器融合、ORB-SLAM、激光SLAM、机器人导航、RTK|GPS|UWB等传感器交流群、SLAM综合讨论群;[自动驾驶方向]深度估计、Transformer、毫米波|激光雷达|视觉摄像头传感器讨论群、多传感器标定、自动驾驶综合群等。[三维重建方向]NeRF、colmap、OpenMVS等。除了这些,还有求职、硬件选型、视觉产品落地等交流群。大家可以添加小助理微信: cv3d007,备注:加群+方向+学校|公司, 小助理会拉你入群。
添加小助理微信:cv3d007, 拉你入群第二步 加入知识星球,问题及时得到解答
针对3D视觉领域的视频课程(三维重建、三维点云、结构光、手眼标定、相机标定、激光/视觉SLAM、自动驾驶等)、源码分享、知识点汇总、入门进阶学习路线、最新paper分享、疑问解答等进行深耕,更有各类大厂的算法工程人员进行技术指导。与此同时,星球将联合知名企业发布3D视觉相关算法开发岗位以及项目对接信息,打造成集技术与就业、项目对接为一体的铁杆粉丝聚集区,6000+星球成员为创造更好的AI世界共同进步,知识星球入口:「3D视觉从入门到精通」
学习3D视觉核心技术,扫描查看,3天内无条件退款
高质量教程资料、答疑解惑、助你高效解决问题第三步 系统学习3D视觉,对模块知识体系,深刻理解并运行
如果大家对3D视觉某一个细分方向想系统学习[从理论、代码到实战],推荐3D视觉精品课程学习网址:www.3dcver.com
基础课程:
[1]面向三维视觉算法的C++重要模块精讲:从零基础入门到进阶
[2]如何学习相机模型与标定?(代码+实战)
[3]ROS2从入门到精通:理论与实战
工业3D视觉方向课程:
[1]机械臂抓取从入门到实战课程(理论+源码)
[2](第二期)从零搭建一套结构光3D重建系统[理论+源码+实践]
[3]三维点云处理:算法与实战汇总
[4]彻底搞懂基于Open3D的点云处理教程!
[5]3D视觉缺陷检测教程:理论与实战!
SLAM方向课程:
[1]深度剖析面向机器人领域的3D激光SLAM技术原理、代码与实战
[1]彻底剖析激光-视觉-IMU-GPS融合SLAM算法:理论推导、代码讲解和实战
[2](第二期)彻底搞懂基于LOAM框架的3D激光SLAM:源码剖析到算法优化
[3]彻底搞懂视觉-惯性SLAM:VINS-Fusion原理精讲与源码剖析
[4]彻底剖析室内、室外激光SLAM关键算法和实战(cartographer+LOAM+LIO-SAM)
[5](第二期)ORB-SLAM3理论讲解与代码精析
视觉三维重建
[1]彻底搞透视觉三维重建:原理剖析、代码讲解、及优化改进)
自动驾驶方向课程:
[1]面向自动驾驶领域目标检测中的视觉Transformer
[2]单目深度估计方法:算法梳理与代码实现
[3]面向自动驾驶领域的3D点云目标检测全栈学习路线!(单模态+多模态/数据+代码)
[4]如何将深度学习模型部署到实际工程中?(分类+检测+分割)