提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
pcl常见点云匹配方法使用方式,包括ICP、NICP、NDT。若想了解大致原理,可参考该地址内容:https://blog.csdn.net/zzr1024/article/details/118567649
一、ICP
#include <pcl/registration/icp.h>
int iterations = 200;
//time.tic();
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setMaximumIterations(iterations);
icp.setInputSource(cloud_src);
icp.setInputTarget(cloud_tar);
icp.setTransformationEpsilon(1e-8);
icp.setEuclideanFitnessEpsilon(1e-5);
icp.setRANSACOutlierRejectionThreshold(2);
icp.setMaxCorrespondenceDistance(2); //添加一个最大距离的阈值,超过最大距离的点不作为对应点。
// 输出配准后点云
icp.align(*cloud_icp);
if (icp.hasConverged()) {
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);
std::cout << std::endl;
std::cout << "transformation_matrix\n" << transformation_matrix << std::endl;
}
else {
PCL_ERROR("\nICP has not converged.\n");
}
二、NICP
#include <pcl/registration/icp.h>
int iterations = 200;
// ICP 参数设置
pcl::IterativeClosestPointWithNormals<pcl::PointNormal, pcl::PointNormal> nicp;
nicp.setInputSource(cloud_src);
nicp.setInputTarget(cloud_tar);
nicp.setMaxCorrespondenceDistance(5);
nicp.setTransformationEpsilon(1e-10);
nicp.setEuclideanFitnessEpsilon(1e-5);
nicp.setMaximumIterations(iterations);
// ICP 迭代
nicp.align(*cloud_nicp);
if (icp.hasConverged()) {
std::cout << "\nNICP has converged, score is " << nicp.getFitnessScore() << std::endl;
std::cout << "\NICP transformation " << iterations << " : cloud_nicp -> cloud_in" << std::endl;
transformation_matrix = nicp.getFinalTransformation().cast<double>();
//print4x4Matrix(transformation_matrix);
std::cout << std::endl;
std::cout << "transformation_matrix\n" << transformation_matrix << std::endl;
}
else {
PCL_ERROR("\nNICP has not converged.\n");
}
三、NDT
#include <pcl/registration/ndt.h>
int iterations = 200;
//初始化正态分布变换(NDT)
pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt;
//设置依赖尺度NDT参数
//为终止条件设置最小转换差异
ndt.setTransformationEpsilon(1e-8);
//为More-Thuente线搜索设置最大步长
ndt.setStepSize(4);
//设置NDT网格结构的分辨率(VoxelGridCovariance)
ndt.setResolution(3);
//设置匹配迭代的最大次数
ndt.setMaximumIterations(iterations);
// 设置要配准的点云
ndt.setInputCloud(cloud_src);
//设置点云配准目标
ndt.setInputTarget(cloud_tar);
ndt.align(*cloud_ndt);
if (ndt.hasConverged()) {
std::cout << "\nNDT has converged, score is " << ndt.getFitnessScore() << std::endl;
std::cout << "\nNDT transformation " << iterations << " : cloud_ndt -> cloud_in" << std::endl;
transformation_matrix = ndt.getFinalTransformation().cast<double>();
//print4x4Matrix(transformation_matrix);
std::cout << std::endl;
std::cout << "transformation_matrix\n" << transformation_matrix << std::endl;
}
else {
PCL_ERROR("\nNDT has not converged.\n");
}
总结
总结了下pcl常用的点云匹配方法,后续遇到新的再继续更新。
总体上NDT耗时会长很多,效果上三者孰优孰劣不好说,听说在开源领域,NICP是效果最好的ICP匹配方法。