点云配准的基本流程:
提取关键点---计算特征描述子---计算坐标及位置的相似度---去除噪声对配准的干扰---刚体变换
迭代最近点算法(ICP)
//头文件
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/registration/icp.h>
//输入输出数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>);
pcl::IterativeClosetPoint<pcl::PointCloud,pcl::PointCloud> icp;
icp.setInputCloud(cloud_in);
icp.setInputTarget(cloud_out);
//设置配准时的参数阈值
icp.setTransformationEpsilon(1e-5); //迭代收敛条件
icp.setMaxCorrespondenceDistance(0.1); //点对间最大距离为10cm
icp.setMaximumIterations(10); //最大迭代次数
//执行icp配准
pcl::PointCloud<pcl::PointXYZ> Result;
icp.align(Result);
//输出转换矩阵
cout << icp.getFinalTransformation() << endl;
正态分布变换算法(NDT)--更适用于大型点云配准
//头文件
#include <pcl/registration/ndt.h>
//创建NDT对象
pcl::NormalDistributionTransform<pcl::PointXYZ,pcl::PointXYZ> ndt;
ndt.setTransformationEpsilon(0.01); //迭代终止条件
ndt.setStepSize(0.1); //最大步长
ndt.setResolution(1.0); //网格分辨率
ndt.setMaximumIterations(50); //最大迭代次数
ndt.setInputCloud(cloud1);
ndt.setInputTarget(cloud2);
//初始变换矩阵
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();
//执行变换
ndt.align(*result,init_guess);