一、概述
PCL中的 pcl::registration::CorrespondenceEstimationNormalShooting
函数用于计算目标点云中与输入点云的法向量具有最小距离的对应点。在估算点对应关系时,主要使用点云中的法向量信息,特别是法向量方向,来估算点云之间的对应关系。它在点对应时通过法向量信息,提高配准的精度,尤其在具有曲率或复杂几何形状的点云上效果显著。
二、代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/registration/correspondence_estimation_normal_shooting.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
int main()
{
// 读取点云
pcl::PointCloud<pcl::PointXYZ>::Ptr source(new pcl::PointCloud<pcl::PointXYZ>); // 源点云
pcl::PointCloud<pcl::PointXYZ>::Ptr target(new pcl::PointCloud<pcl::PointXYZ>); // 目标点云
if (pcl::io::loadPCDFile<pcl::PointXYZ>("lamp.pcd", *source) == -1 ||
pcl::io::loadPCDFile<pcl::PointXYZ>("lamp1.pcd", *target) == -1)
{
PCL_ERROR("Couldn't read the PCD files!\n");
return -1;
}
// 基于法线信息寻找对应点对
pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> ne;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
ne.setNumberOfThreads(8);
ne.setInputCloud(source);
ne.setSearchMethod(tree);
ne.setKSearch(50);
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
ne.compute(*normals);
// 获取匹配点对
pcl::registration::CorrespondenceEstimationNormalShooting<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> registration;
registration.setInputSource(source);
registration.setSourceNormals(normals); // 设置源点云法线
registration.setInputTarget(target); // 设置目标点云
registration.setKSearch(50); // 设置邻域搜索的点个数
pcl::Correspondences correspondences;
registration.determineCorrespondences(correspondences, 1.5);// 对应点结果和匹配点之间的最短距离
// 输出结果到渲染窗口可视化
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("CorrespondenceEstimationNormalShooting"));
viewer->addPointCloud<pcl::PointXYZ>(source, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(source, 0, 255, 0), "source");
viewer->addPointCloud<pcl::PointXYZ>(target, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(target, 255, 0, 0), "target");
viewer->addCorrespondences<pcl::PointXYZ>(source, target, correspondences, "correspondence");
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}