学习PCL库:PCL中的配准模块介绍

前言

将多个数据集合并成一个全局一致的模型通常使用一种称为"配准"的技术来完成。其关键思想是识别数据集之间的对应点,并找到一个最小化对应点之间距离的变换关系。由于对应点的查找受到数据集的相对位置和方向的影响,因此需要重复这个过程。一旦最小化误差降到给定的阈值以下,就可以说完成了配准。pcl_registration库实现了众多点云配准算法,适用于有序和无序点云的数据集。

有序点云和无序点云

所谓有序点云,通常以规则的网格或栅格形式表示,其中点的排列遵循某种规则,例如在二维平面上的图像或在三维中的体素格子(voxels)。那么有序点云的特征方面,由于点云的排列有规律,因此有序点云通常包含丰富的拓扑和结构信息,这些点云可以表示物体的外部形状和内部结构,因此通常更适用于需要精确建模或分析的应用那么针对有序点云的配准方法通常更容易,因为点的排列有序,可以利用这种结构来更准确地找到对应点,从而进行变换和配准,通常使用的方法包括特征匹配、最小二乘法等方法。

对于无序点云,在数据结构上由于点的排列没有明显的规则或结构,它们以离散的方式表示物体的表面或环境。所以无序点云的特征通常缺乏明显的拓扑或结构信息,因此不容易直接提取对象的形状或内部特征,它们主要用于表征物体的外部几何形状。所以无序点云的配准通常更具挑战性,因为没有明显的结构可供利用,无序点云的配准通常需要使用特征点提取和匹配、迭代最近点(ICP)等更复杂的算法来实现。相同的点云可以由两个完全不同的矩阵表示,也是典型的无序点云 ,如下图所示:

图片来自作者“点云”的知乎

PCL Registration API介绍

pcl::registration::ConvergenceCriteria 用于控制点云配准算法的迭代终止条件。在点云配准中,通常需要迭代地调整一个点云相对于另一个点云的变换,以最小化它们之间的距离或误差。ConvergenceCriteria 允许用户定义何时算法应停止迭代,以达到所需的匹配精度。可以从这个基类派生的典型收敛准则包括:(这三个迭代终止条件这也是面试点云算法时偶尔考的问题之一)

  • 已达到最大迭代次数。
  • 变换(R、t)无法进一步更新(当前值与先前值的差异小于某一阈值)。
  • 当前对应关系集与先前对应关系集之间的均方误差(MSE)小于某个阈值。

pcl::registration::CorrespondenceEstimationBase 是PCL(Point Cloud Library)中的一个基类,用于点云配准(registration)过程中的对应点估计,它的主要作用是计算两个点云之间的对应关系,以帮助实现点云的配准。这个类的实现功能是建立点云之间的对应关系,可以用于多种点云配准算法中,包括Iterative Closest Point (ICP) 等。

pcl::registration::CorrespondenceEstimation 用于估计点云中两个点集之间的对应关系,这个类的主要作用是在两个点云之间建立点与点之间的对应关系,以便在点云配准和对齐过程中使用这些对应关系。该类还可用于在两个点云之间匹配具有相似特征的点,这对于从多个视角捕获的点云的配准非常有用。代码示例:

代码语言:javascript
复制
pcl::PointCloud::Ptr source, target;
// ... 读取或填充 source 和 target
// 创建 CorrespondenceEstimation 对象
pcl::CorrespondenceEstimationest;
est.setInputSource(source);
est.setInputTarget(target);
pcl::Correspondences all_correspondences;
// 确定所有的互相对应关系
est.determineReciprocalCorrespondences(all_correspondences);

CorrespondenceEstimation 用于确定源点云 source 和目标点云 target 之间的对应关系。determineReciprocalCorrespondences 方法被用来确定所有的互相对应关系,这意味着它会查找同时在源和目标点云中找到的对应点,并将它们存储在 all_correspondences 中。

pcl::registration::CorrespondenceEstimationBackProjection 类主要功能是估算源点云(PointSource)和目标点云(PointTarget)之间的对应关系,即找到源点云中的点与目标点云中的点之间的匹配。这对于点云配准任务至关重要,因为在配准过程中需要确定哪些点在源和目标点云之间是相互对应的。这个类通过执行以下步骤来实现其功能:

  • 特征计算:首先它会计算源点云和目标点云的特征,通常包括法线(NormalT)信息。
  • 背投法计算:接着它使用反投法(back-projection)来估计源点云中的点在目标点云中的估计位置,这个过程可以理解为根据源点云中的点与目标点云的特征之间的关系,来估计它们在目标点云中的位置。
  • 对应关系建立:最后它建立源点云中的点到目标点云中的点的对应关系,即找到了匹配点对。

pcl::registration::CorrespondenceEstimationNormalShooting 它用于计算目标点云中与输入点云上计算的法向量具有最小距离的对应点。在估算点对应关系时,主要使用点云中的法向量信息,特别是法向量方向,来估算点云之间的对应关系。它在点对应时考虑了法向量的信息,以提高配准的精度,尤其在具有曲率或复杂几何形状的点云上效果显著。代码示例

代码语言:javascript
复制
pcl::PointCloud::Ptr source, target;
// ... 读取或填充源点云(source)和目标点云(target)
pcl::CorrespondenceEstimationNormalShooting
  est;
est.setInputSource(source); // 设置源点云
est.setSourceNormals(source); // 设置源点云的法向量
est.setInputTarget(target); // 设置目标点云
est.setKSearch(10); // 测试每个源点的前10个对应关系,并返回最佳的对应关系
pcl::Correspondences all_correspondences;
// 确定所有的对应关系
est.determineCorrespondences(all_correspondences);

pcl::registration::CorrespondenceEstimationOrganizedProjection这个类的主要作用是估计两个有序点云之间的对应点,有序点云通常是来自深度相机的数据。该类实现了一些特定的对应点估计方法,这些方法考虑了有序点云的特殊属性,如相机投影,通过使用相机内外参,将源点云投影到目标点云上来计算对应点,这有助于提高对应点估计的准确性。这个类充分利用了有序点云的结构,以提高对应点估计的速度。

pcl::registration::CorrespondenceRejector是一个用于点云配准(点云间对应关系的建立)的功能组件,主要作用是在点云配准的过程中,识别和剔除不正确的或噪声点对应关系,以减小配准误差和提高最终的配准质量。它可以帮助滤除配准中的异常点,改善数据质量,减小误匹配的影响。这在处理实际场景中的点云数据时非常有用,因为点云数据可能会受到噪声、不完整性或遮挡的影响。CorrespondenceRejector提供了多种策略和方法,用于拒绝不希望的点云对,例如:

  • DistanceRejector:基于点云点之间的距离来拒绝对应关系,可以设置一个距离阈值,如果两个点之间的距离大于该阈值,则拒绝这对点的对应关系。
  • MedianDistanceRejector:与DistanceRejector类似,但不是简单地使用固定的阈值,而是根据距离的中值来动态确定距离阈值。
  • OneToOneRejector:用于确保每个点只能与一个点匹配,防止一个点匹配到多个点的情况。
  • SampleConsensusRejector:基于采样一致性方法,拒绝不符合拟合模型的点对应关系,通常用于配准时采用模型匹配的情况

关于该类的功能使用和介绍可阅读这篇论文:Robot bin picking: 3D pose retrieval based on Point Cloud Library

pcl::registration::DataContainerInterface 提供了一个通用接口,用于计算输入点云和目标点云中对应点之间的对应得分。

pcl::registration::CorrespondenceRejectorDistance 用于点云配准(registration)时的对应点剔除,其主要功能和作用是基于距离标准来拒绝不符合指定距离条件的点云对应关系,这有助于提高配准的精确性和减少可能的误匹配。用户可以通过设置距离阈值来指定哪些点对应该被拒绝,通常距离阈值是一个正数,表示两点之间的最大距离。如果两个点之间的距离超过了这个阈值,它们将被拒绝作为对应点。

pcl::registration::CorrespondenceRejectorFeatures通常用于点云配准(registration)过程中,用于拒绝或筛选匹配点之间的对应关系。它的主要功能是通过分析匹配点的特征来决定是否接受或拒绝它们作为最终的对应关系。这个类通常会用于一些点云配准算法的后处理步骤,以帮助提高配准的质量和准确性。

pcl::registration::CorrespondenceRejectorMedianDistance 实现了一种基于对应关系之间的中值距离阈值的简单对应关系拒绝方法。根据这些距离的中值来判断是否接受或拒绝该对应关系。如果一对对应点的距离大于中值的某个倍数(阈值),则该对应关系将被拒绝,通过排除这些异常对应关系,可以提高配准的精度,降低对配准结果的干扰。这段代码是从libpointmatcher(https://github.com/ethz-asl/libpointmatcher)移植而来。

pcl::registration::CorrespondenceRejectorOneToOne用于点云配准中的对应点筛选,该类的主要功能是从匹配点对中筛选出一对一的对应点关系,消除对应关系中重复匹配索引的对应点方法,以提高点云配准的准确性和可靠性。

pcl::registration::CorrespondenceRejectionOrganizedBoundary 类实现了一种简单的点对应关系拒绝度量。对于每一对点对应,它检查它们是否位于轮廓的边界上,这些点对应可能会导致不准确的配准结果,通过计算在点周围的一个窗口中的NaN的数量来完成的(用户可以设置阈值和窗口大小)。因为在点云配准过程中,边界点通常受到不完整数据或扫描仪感知的限制,因此它们的点对应可能不够准确,通过筛选掉这些点对应,可以提高配准的精度和稳定性。注意:这里要求源点云和目标点云都需要是有序的,否则所有的点对应都将被拒绝。

pcl::registration::CorrespondenceRejectorPoly 通过利用两个点集之间的低级别特征和位姿不变的几何约束,使用输入对应关系在每个模型上形成具有用户可指定基数的虚拟多边形,然后以位姿不变的方式检查这些多边形(即边长必须大致相等),并通过对这些边长进行阈值化来执行拒绝。参考文章:

Pose Estimation using Local Structure-Specific Shape and Appearance Context.

pcl::registration::CorrespondenceRejectorSampleConsensus 实现了使用随机样本一致性(Random Sample Consensus,RANSAC)的方法进行对应点拒绝,以识别内点(inliers)并拒绝离群点(outliers)。

pcl::registration::CorrespondenceRejectorSurfaceNormal主要功能是利用点云中的法线信息来排除不符合法线一致性的点云对应关系。这对于点云配准非常重要,因为它可以帮助排除那些法线不一致的点云,从而提高配准的精度和鲁棒性。法线在点云中通常用于描述表面的方向,因此具有一致法线的点云对应更可能是正确的。原始代码来自libpointmatcher:

https://github.com/ethz-asl/libpointmatcher)

pcl::registration::CorrespondenceRejectorTrimmed主要功能在于筛除两个点云中不满足距离阈值条件的点对。这对于提高点云配准的质量非常重要,因为在点云匹配过程中可能会出现不完全匹配或异常点的情况。通过筛除这些不合格的点对,可以消除配准中的噪声和误匹配,提高了最终的配准质量。

pcl::registration::ELCH 表示 "Explicit Loop Closing Heuristic",该算法旨在改进点云配准的效率和准确性,特别是在处理大规模点云数据时。ELCH 可以检测和处理点云中的循环闭合情况,即当点云中的某一部分在其它部分中重复出现时。这对于 SLAM(Simultaneous Localization and Mapping)应用非常关键。ELCH 算法通过使用显式的启发式方法,用回环检测来提高配准的效率和准确性,这使得它在处理大规模点云数据时更为有效。

pcl::GeneralizedIterativeClosestPoint(GICP)该算法扩展了传统的迭代最近点(Iterative Closest Point,ICP)算法,通过考虑点云的拓扑结构来提高匹配的准确性,特别是在有序点云和含有噪声的数据情况下。与传统的ICP不同,GICP考虑了点云的拓扑结构,因此更适合用于有序点云和含有噪声的点云数据。这使得它在更复杂的场景中表现更好,GICP提供了一种评估配准质量的方法,通过计算配准后点云的重叠度和平均距离等指标。GeneralizedIterativeClosestPoint是ICP算法的一种变体,它实现了由Alex Segal等人描述的广义迭代最近点算法。在Generalized_ICP文章中,该方法基于使用各向异性代价函数来优化在最近点分配完成后的对齐过程。原始代码使用了GSL和ANN库,而PCL库中实现使用了FLANN库和牛顿法进行优化。

pcl::GeneralizedIterativeClosestPoint6D 是专门用于6自由度(6-DOF)的点云配准,这种配准方法在计算机视觉和机器人领域用于将两个点云(通常是3D扫描或传感器数据)对齐,并估计它们之间的旋转和平移变换,以使它们最匹配,以便它们在相同坐标系下对齐。参考文章:Color Supported Generalized-ICP.

pcl::registration::GraphHandler 用于处理点云图形数据,它主要用于点云的图形建模和关联性分析。该类允许用户构建点云之间的关系图,其中每个点云可以与其他点云相关联,形成一个图形结构。这有助于表示多个点云之间的相对位置和拓扑关系。通过图形结构,您可以进行拓扑分析和关联性分析,例如查找点云之间的匹配、连接性和其他关联性信息。还提供了可视化工具,允许用户可视化点云之间的图形结构,以更好地理解它们之间的关系。

pcl::registration::GraphOptimizer用于解决点云配准中的参数优化问题,通常是在多个点云之间进行变换以实现最佳的点云配准。这个类的目标是通过优化变换参数,最小化点云之间的距离或误差,以改进配准质量。该类可以处理多个点云之间的复杂关系,并利用图优化算法来调整这些关系,以获得全局最优的配准结果。

pcl::registration::FPCSInitialAlignment 是一个功能强大的初始对准算法,用于对准源点云和目标点云以准备后续的点云配准操作,这个算法的全称是 Fast Point Cloud Stitching Initial Alignment(FPCS),它的主要作用是找到源点云和目标点云之间的初始变换,使它们尽可能地对齐。FPCS算法的设计目标之一是提供快速且高效的初始对齐。这可以帮助减少整个点云配准过程的计算时间,该算法在处理噪声、缺失数据和初始偏差等情况时表现出较强的鲁棒性,因此在实际应用中通常能够处理复杂的点云数据。4-points congruent sets for robust pairwise surface registration这篇文献描述了用于稳健的成对表面配准的四点共形集的计算方法,可能是 FPCSInitialAlignment 算法的理论基础。

pcl::registration::KFPCSInitialAlignment 是基于Point-to-Point的点云配准方法的一部分,它的主要作用是用于初始化配准算法,特别是用于初始化Point-to-Point的配准算法,以改善配准的收敛性和稳定性。该方法还可以计算点云中的表面法线和特征描述符,这些特征可以用于改进配准的质量和速度。参考文献

Markerless point cloud registration with keypoint-based 4-points congruent sets它使用关键点检测技术来计算点云中的关键点,然后根据这些关键点来计算四点一致集,以帮助点云的配准。这种方法可以提高点云配准的精度和稳定性,尤其是在无标记的情况下。

pcl::SampleConsensusInitialAlignment 类的主要功能是通过采样一组点来寻找两个点云之间的初始对齐变换,这个类主要用于点云配准的初始阶段,它能够识别并估计两个点云之间的粗略变换(平移和旋转)

pcl::IterativeClosestPointNonLinear 实现了非线性的 ICP 算法,通过最小化两个点云之间的距离来找到最佳的刚性变换,以实现点云的配准。这个算法可用于解决从不同视角或位置采集的点云数据之间的配准问题。是一种使用Levenberg-Marquardt优化后端的ICP变种,最终的变换是以四元数进行优化的。

pcl::registration::IncrementalRegistration 用于实现增量式点云配准,即将多个点云数据集逐步配准到一个全局坐标系中。这有助于合并多个数据源生成一个更大的点云或建立三维地图。代码示例

代码语言:javascript
复制
IterativeClosestPoint::Ptr icp
  (new IterativeClosestPoint);
icp->setMaxCorrespondenceDistance(0.05);
icp->setMaximumIterations(50);
IncrementalRegistrationiicp;
iicp.setRegistration(icp);
while (true) {
  PointCloud::Ptr cloud(new PointCloud);
  read_cloud(*cloud);
  iicp.registerCloud(cloud);
  PointCloud::Ptr tmp(new PointCloud);
  transformPointCloud(*cloud, *tmp, iicp.getAbsoluteTransform());
  write_cloud(*tmp);
}

pcl::JointIterativeClosestPoint 扩展了 ICP(迭代最近点)算法以适用于共享相同变换的多个帧。这在使用多个观测来解决相机外部参数时非常有用。当给定单一点云对时,这等同于标准的 ICP 算法。

pcl::registration::LUM 表示 "Locally Unique Minima"(局部唯一极小值),是PCL库中的一个用于点云配准的算法。它基于Lu和Milios的算法,实现了一种全局一致的扫描匹配,主要用于建图和SLAM(Simultaneous Localization and Mapping)任务。可以理解为GraphSLAM算法,其中用一个图来管理配准数据:

  • 顶点(Vertices)表示不同位姿(姿势或位置),并包含点云数据和相对变换信息。
  • 边(Edges)表示位姿之间的约束关系,并包含两个点云之间的对应关系数据。
代码语言:javascript
复制
pcl::registration::LUMlum;
// 将点云作为SLAM图的顶点添加
lum.addPointCloud(cloud_0);
lum.addPointCloud(cloud_1);
lum.addPointCloud(cloud_2);
// 使用您喜欢的对应关系估计算法
corrs_0_to_1 = someAlgo(cloud_0, cloud_1);
corrs_1_to_2 = someAlgo(cloud_1, cloud_2);
corrs_2_to_0 = someAlgo(lum.getPointCloud(2), lum.getPointCloud(0));
// 将对应关系结果作为SLAM图的边添加
lum.setCorrespondences(0, 1, corrs_0_to_1);
lum.setCorrespondences(1, 2, corrs_1_to_2);
lum.setCorrespondences(2, 0, corrs_2_to_0);
// 更改计算参数
lum.setMaxIterations(5);
lum.setConvergenceThreshold(0.0);
// 执行实际的LUM计算
lum.compute();
// 返回合并的点云结果
cloud_out = lum.getConcatenatedCloud();
// 返回单独的点云变换
for (int i = 0; i < lum.getNumVertices(); i++) {
  transforms_out[i] = lum.getTransformation(i);
}

pcl::NormalDistributionsTransform(NDT)它是一种三维正态分布变换方法,用于将两个点云进行精确的配准,即找到它们之间的相对变换关系,以便它们可以对齐。pcl::NormalDistributionsTransform基于正态分布的理论,用于点云的配准,特别适用于处理有噪声、遮挡或不完整数据的情况。基于Magnusson博士的博士论文:The Three-Dimensional Normal-Distributions Transform-an Efficient Representation for Registration, Surface Analysis, and Loop Detection.

pcl::PPFRegistration用于基于点云的 PPF(Point Pair Features),一种用于描述点云局部形状的特征来对齐两个点云,从而实现点云配准的目的。参考文章:Model Globally, Match Locally: Efficient and Robust 3D Object Recognition

pcl::SampleConsensusPrerejective 是用于姿态估计和点云配准的类。使用了一种称为“prerejection”的技术,将其插入标准的RANSAC(随机抽样一致性)姿态估计循环中,以避免验证那些可能错误的姿态假设。这通过局部姿态不变的几何约束来实现,与CorrespondenceRejectorPoly类中的实现类似。为了鲁棒地对齐部分或遮挡的模型,该算法仅使用内点(inliers)进行拟合误差评估,即距离欧几里得阈值更近的点。这个阈值可以使用 setInlierFraction() 方法进行设置。该算法的“贪婪度”或预拒绝的程度可以使用 setSimilarityThreshold() 方法进行指定,范围为 [0, 1],其中0表示禁用,1表示最大程度的拒绝。参考文献:Pose Estimation using Local Structure-Specific Shape and Appearance Context. 这篇论文描述了使用局部结构特定的形状和外观上下文进行姿态估计的方法,这些方法在pcl::SampleConsensusPrerejective类中得到了实现。

pcl::registration::TransformationEstimation 类来估算将源点云变换为与目标点云对齐所需的刚性变换矩阵

这个类主要基于以下情况之一来进行变换矩阵的估算:

  • 对应向量(correspondence vectors)。
  • 具有相同大小的两个点云(源点云和目标点云)。
  • 一个点云(源点云)和一组索引,以及另一个点云(目标点云)。
  • 具有相同大小的两个点云,每个点云都有一组索引(源点云和目标点云)。

pcl::registration::TransformationEstimation2D 它实现了简单的二维刚性变换估计功能,用于给定一对数据集。该类的主要作用是估计两个数据集之间的刚性变换,包括平移(x,y)和旋转(theta),使它们在平面上对齐。这通常用于在点云配准或拼接中,将两个点云数据集对齐到一个共同的参考平面(通常是z = 0平面)上。

pcl::registration::TransformationEstimation3Point 是用于估算点云之间的变换矩阵的类,它的主要作用是根据三对对应点的坐标来估算点云之间的刚体变换。这个类的实现是为了处理以下情况:

  • 三对点的对应关系,用于平面到平面的情况。
  • 两个具有三个点的点云(源和目标)。
  • 一个点云和一个包含三个索引的集合(源点云和目标点云之间的对应关系)。
  • 两个点云和两组包含三个索引的集合(分别用于源点云和目标点云)。

pcl::registration::TransformationEstimationDQ 它实现了双四元数(Dual Quaternion)方法来估计点云之间的变换以实现配准。这个方法的主要作用是将两个点云之间的对应关系(点与点之间的对应关系)用双四元数来表示,并从中估计出最佳的刚性变换(旋转和平移),以使两个点云尽可能吻合。关于双四元数方法在点云配准中的应用,可以参考论文:On the role of quaternions in rigid body motion: A tutorial

pcl::registration::TransformationEstimationDualQuaternion 的主要功能是估计两个点云之间的刚体变换,以便将它们对齐,它采用点云之间的对应点(通常是特征点或关键点)作为输入,然后使用双四元数的数学模型来计算最佳的刚体变换,使两个点云之间的对应点之间的误差最小化。这可以用于多种应用,包括点云配准、SLAM和三维重建。

pcl::registration::TransformationEstimationLM 是实现了基于Levenberg-Marquardt算法的变换估计,用于将给定的对应点云配准到一起。这个功能主要用于求解两个点云之间的刚体变换(旋转和平移),以使它们最佳地对齐。

pcl::registration::TransformationEstimationPointToPlane 用于估计两个点云之间的刚性变换,以最小化点到平面的距离误差。它适用于需要考虑点云中每个点与对应平面之间的关系的情况,这种距离度量通常比点到点距离更适合于表面重建和点云对齐等应用。

pcl::registration::TransformationEstimationPointToPlaneLLS 实现了线性最小二乘(LLS)估计,用于最小化两个具有法向量的对应点云之间的点到平面距离。具体来说,它用于点云配准问题,其中一个点云(通常称为源点云)与另一个点云(通常称为目标点云)进行配准,目标点云的每个点都有一个法向量。

pcl::registration::TransformationEstimationSVD它用于通过奇异值分解(SVD)来估计点云之间的刚体变换,以实现点云配准,这个类的主要作用是计算变换矩阵,将两个点云之间的对应点对齐到一个共同的坐标系中,以便进行后续的配准操作。

pcl::registration::TransformationValidation用于验证通过变换估计(TransformationEstimation)找到的变换的正确性,这个类主要用于点云配准(registration)的上下文中,验证估计的变换是否适合将源点云与目标点云对齐。这个评估通常以分数或置信度度量的形式输出,用于衡量变换的准确性和可行性。它可以用来确定估计的变换是否在点云配准中是可靠的,或者是否需要进一步的调整或改进。输出是一个分数或置信度度量,用于指示估计的变换的质量和可靠性。

代码语言:javascript
复制
// 计算变换的得分 
double score = validation.computeTransformationScore();

pcl::registration::WarpPointRigid 是用于执行刚体变换(Rigid Transformation)操作,包括三维旋转和三维平移。这个类的主要目的是将点云中的点进行刚体变换,从而实现配准(registration)或对齐(alignment)的任务。刚体变换是一种保持点云内部点相对位置关系不变的变换,通常用于将不同采集时间或视角下的点云对准。 WarpPointRigid 不仅可以用于点云的配准,还可以用于其他需要刚体变换的应用,如目标跟踪或SLAM。