[PCL] 点云配准

mac2023-01-31  17

由于点云的不完整,旋转错位、平移错位等,使得要得到的完整的点云就需要对局部点云进行配准,为了得到被测物体的完整数据模型,需要确定一个合适的坐标系,将从各个视角得到的点集合并到统一的坐标系下形成一个完整的点云,然后就可以方便进行可视化的操作,这就是点云数据的配准。点云的配准有手动配准、依赖仪器的配准和自动配准,点云的自动配准技术是通过一定的算法或者统计学规律利用计算机计算两块点云之间错位,从而达到两块点云自动配准的效果,其实质就是把不同的坐标系中测得到的数据点云进行坐标系的变换,以得到整体的数据模型,问题的关键是如何让得到坐标变换的参数R(旋转矩阵)和T(平移向量),使得两视角下测得的三维数据经坐标变换后的距离最小,目前配准算法按照过程可以分为整体配准和局部配准。PCL中有单独的配准模块,实现了配准相关的基础数据结构,和经典的配准算法如ICP。

PCL中实现配准算法以及相关的概念

两两配准的简介:一对点云数据集的配准问题是两两配准(pairwise registration)。通常通过应用一个估计得到的表示平移和旋转的4*4刚体变换矩阵来使得一个点云的数据集精确的与另一个点云数据集(目标数据集)进行完美的配准。

具体的实现步骤:

首先从两个数据集中按照同样的关键点选取的标准,提取关键点。对选择所有的关键点分别计算其特征描述子。结合特征描述子在两个数据集中的坐标位置,以两者之间的特征和位置的相似度为基础,来估算它们的对应关系,初步的估计对应点对。假设数据有噪声,除去对配准有影响的错误的对应点对。利用剩余的正确的对应关系来估算刚体变换,完整配准。

对应估计(correspondences estimation)

假设我们已经得到扫描的点云数据获的两组特征向量,在此基础基础上,我们必须找到,相似特征再确定数据的重叠部分,然后才能进行配准,根据特征的类型PCL使用不同的方法来搜索特征之间的对应关系。

使用点匹配时,使用点的XYZ的坐标作为特征值,针对有序点云和无序点云数据的不同的处理策略:

穷举配准(brute force matching)kd树——数最近邻查询(FLANN)在有序点云数据的图像空间中查找在无序点云数据的索引空间中查找

对应关系的去除(correspondence rejection)

由于噪声的影响,通常并不是所有估计的对应关系都是正确的,由于错误的对应关系对于最终的刚体变换矩阵的估算会产生负面的影响,所以必须去除它们,可以采用随机采样一致性估计,或者其他方法剔除错误的对应关系,最终使用对应关系数量只使用一定比例的对应关系,这样既能提高变换矩阵的估计精度也可以提高配准点的速度。

变换矩阵的估算(transormation estimation)

估算对应矩阵的步骤如下

在对应关系的基础上评估一些错误的度量标准。在摄像机位姿(运动估算)和最小化错误度量标准下估算一个刚体变换。优化点的结构。使用刚体变换把源旋转/平移到与目标所在的同一坐标系下,用所有点的一个子集或者关键点运算一个内部的ICP循环。进行迭代,直到符合收敛性判断标准为止。

迭代最近点算法(Iterative CLosest Point简称ICP算法)

ICP算法对待拼接的2片点云,首先根据一定的准则确立对应点集P与Q,确定对应点对的个数,然后通过最小乘法迭代计算最优的坐标变换,即旋转矩阵R和平移矢量t,使得误差函数最小,ICP处理流程分为四个主要的步骤:

对原始点云数据进行采样确定初始对应点集去除错误对应点对坐标变换的求解

应用实例

1. 利用SURF特征检测算子进行点云配准和实现全景点云拼接:源码

效果:

2. 基于IPC点云配准:源码

效果:

可以从试验结果看得出变换后的点云只是在x轴的值增加了固定的值0.7,然后由这目标点云与源点云计算出它的转换矩阵,明显可以看出最后一行的x值为0.7。

正态分布变换进行配准(Normal Distributions Transform)

正态分布算法用来确定两个大型点云之间的刚体变换,正态分布变换算法是一个配准算法,它应用于三维点的统计模型,使用标准最优化技术来确定两个点云间的最优匹配,因为其在配准的过程中不利用对应点的特征计算和匹配,所以时间比其他方法比较快。

示例

// 初始化正态分布(NDT)对象 pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt; // 根据输入数据的尺度设置NDT相关参数 ndt.setTransformationEpsilon (0.01); //为终止条件设置最小转换差异 ndt.setStepSize (0.1); //为more-thuente线搜索设置最大步长 ndt.setResolution (1.0); //设置NDT网格网格结构的分辨率(voxelgridcovariance) //以上参数在使用房间尺寸比例下运算比较好,但是如果需要处理例如一个咖啡杯子的扫描之类更小的物体,需要对参数进行很大程度的缩小 //设置匹配迭代的最大次数,这个参数控制程序运行的最大迭代次数,一般来说这个限制值之前优化程序会在epsilon变换阀值下终止 //添加最大迭代次数限制能够增加程序的鲁棒性阻止了它在错误的方向上运行时间过长 ndt.setMaximumIterations (35); ndt.setInputSource (filtered_cloud); //源点云 ndt.setInputTarget (target_cloud); //目标点云 // 设置使用机器人测距法得到的粗略初始变换矩阵结果 Eigen::AngleAxisf init_rotation (0.6931, Eigen::Vector3f::UnitZ ()); Eigen::Translation3f init_translation (1.79387, 0.720047, 0); Eigen::Matrix4f init_guess = (init_translation * init_rotation).matrix (); // 计算需要的刚体变换以便将输入的源点云匹配到目标点云 pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud (new pcl::PointCloud<pcl::PointXYZ>); ndt.align (*output_cloud, init_guess); //这个地方的output_cloud不能作为最终的源点云变换,因为上面对点云进行了滤波处理 std::cout << "Normal Distributions Transform has converged:" << ndt.hasConverged () << " score: " << ndt.getFitnessScore () << std::endl; // 使用创建的变换对为过滤的输入点云进行变换 pcl::transformPointCloud (*input_cloud, *output_cloud, ndt.getFinalTransformation ()); // 保存转换后的源点云作为最终的变换输出 pcl::io::savePCDFileASCII ("room_scan2_transformed.pcd", *output_cloud);

效果

交互式ICP可视化

基于IPC对加载点云进行刚体变换,之后,使用ICP算法将变换后的点云与原来的点云对齐。

示例

// 迭代最近点算法 time.tic (); //时间 pcl::IterativeClosestPoint<PointT, PointT> icp; icp.setMaximumIterations (iterations); //设置最大迭代次数iterations=true icp.setInputSource (cloud_icp); //设置输入的点云 icp.setInputTarget (cloud_in); //目标点云 icp.align (*cloud_icp); //匹配后源点云 icp.setMaximumIterations (1); // 设置为1以便下次调用 std::cout << "Applied " << iterations << " ICP iteration(s) in " << time.toc () << " ms" << std::endl; if (icp.hasConverged ())//icp.hasConverged ()=1(true)输出变换矩阵的适合性评估 { std::cout << "\nICP has converged, score is " << icp.getFitnessScore () << std::endl; std::cout << "\nICP transformation " << iterations << " : cloud_icp -> cloud_in" << std::endl; transformation_matrix = icp.getFinalTransformation ().cast<double>(); print4x4Matrix (transformation_matrix); } else { PCL_ERROR ("\nICP has not converged.\n"); return (-1); }

运行结果

点云配准与点云拼接

点云拼接,配准,注册说的是同一个概念,就是寻找对齐不同点云之间的空间变换的过程。找到这种转换的目的包括将多个点云拼接为全局一致的模型,并将新的测量值映射到已知的点云以识别特征或估计其姿势。

寻找不同点云空间变换矩阵有两种方法:

1、拍摄图像或使用扫描设备扫描时记录每个点云的相对位姿,即平移矩阵、旋转矩阵。直接根据平移和旋转矩阵对点云进行变换、拼接。此种方法要求拍摄图像或扫描点云数据时记录相机或扫描设备与每个点云的相对位姿,从而可求出每个点云之间相对位姿。但一般情况下我们不可得到或得不到精确的空间变换矩阵。所以,我们常用以下方法。

2、提取点云特征,进行特征匹配,找到点云重叠部分进而可求得点云之间空间变换矩阵。特征提取有很多种方法,公众号前面也有相关文章,此处不详细介绍。可能以后会将这一部分专门整理一下。

拼接成功的判定

拼接成功的判定,最关键的是“成功”的定义。一般是计算两个点云的重叠区域的大小,重叠区域可以根据点云特征来加权计算。当重叠区域面积或者比例大于一定的阈值,就判定为成功。需要注意的是,有时候用户期望的变换,并不是“最好的”。

如何融合已经拼接的数据?

拼接好的点云数据,会有很多重叠部分,对于重叠部分,一般由两种方法:平均融合和去除重叠。顾名思义,平均融合就是将重叠部分的点平均起来。去除重叠就是在重叠部分只取其中一帧的数据。

·多帧点云,往往由于系统误差原因,重叠部分的点是不能完美重合在一起的。多帧数据平均融合,会损失掉一些数据细节。去除重叠,只取一帧的做法,可以保留住点云的细节。

·点云去除重叠,需要有个重叠判定条件,一般是设置一个点云的影响范围,范围内的点会被过滤掉。就如同一个筛子一样,过滤范围越大,筛子的缝隙越小。一般可以取点云的平均间距作为过滤范围,如果点云误差比较大,可以增大过滤范围。避免出现不同帧的点云在重叠处相互渗透的情况,相互渗透会产生噪音。但去除重叠的时候,在重叠交界处,会有接缝痕迹。

如何去掉点云的重影:

多帧点云注册去除重叠后,得到一个整体点云后,有时候会出现局部点云有重影的情况。常见的原因是数据本身有误差,有微小形变,刚体变换不可能把多帧点云完全对齐。根据点云处理的工作流程,下面介绍几种去除重影的方法:

1)非刚体ICP注册:既然数据有误差,刚体变换无法完全对齐点云,可以引入非刚体注册。对于两帧数据的注册,可以应用非刚体ICP。

2)非刚体全局注册:对于多帧数据的注册,可以应用非刚体全局注册。

3)点云去除重叠:在点云去除重叠的时候,也可以融合重叠接缝处的误差痕迹。具体效果可以参考“如何融合已经注册对齐的数据”部分的讲解。

4)点云去除重影:如果用户已经得到了一个整体点云,并且有了重影,没有办法应用非刚体注册。那么可以先检测出点云的重影部分,再删除掉这些局部点云。

 

最新回复(0)