PCL 寻找点云对应点对关系(Registration_CorrespondenceEstimation)

注意:本示例为PCL中寻找对应点对的基础方法,无需输入法向量或者直方图等其他特征,直接输入点云就可计算。

1.原理

PCL源代码中没有相关论文名称,也没有某种算法的关键字。无从查找原理。所以本示例不介绍原理。

但本方法在点对匹配中较常用。

2.关键函数

(1)本类类名

pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> registration;

3.代码

#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.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>);			// 目标点云
	pcl::io::loadPCDFile("D:/code/csdn/data/plane.pcd", *source);
	pcl::io::loadPCDFile("D:/code/csdn/data/plane1.pcd", *target);

	// 寻找对应点对
	pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> registration;
	registration.setInputSource(source);
	registration.setInputTarget(target);									// 设置目标点云
	pcl::Correspondences correspondences;
	registration.determineCorrespondences(correspondences, 5);				// 对应点结果和匹配点之间的最短距离

	/****************展示********************/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("CorrespondenceEstimationBackProjection"));
	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;
}

4.结果展示

<think>我们正在处理用户的问题:在PCL中基于法线信息查找匹配点对。用户询问的是PCL normal-based correspondence estimation。 根据引用[4]中提到,点云配准中可能会使用法线信息。在PCL中,有一个类叫做`pcl::registration::CorrespondenceEstimationNormalShooting`,它使用法线投影的方法来估计对应点。此外,还有一种常见的方法是利用点的位置和法线信息一起进行匹配,例如`pcl::registration::CorrespondenceEstimationBackProjection`。 然而,用户可能更关心如何使用PCL中现有的类来实现基于法线的匹配点对查找。PCL中提供了多种对应点估计方法,其中一些方法利用了法线信息。 常见的基于法线的对应点估计方法包括: 1. CorrespondenceEstimationNormalShooting:通过从源点云中的点沿着法线方向投影到目标点云寻找对应点。 2. CorrespondenceEstimationBackProjection:通过将目标点云中的点反向投影到源点云(考虑法线)来寻找对应点,这种方法对噪声更鲁棒。 3. 也可以使用普通的对应点估计(如CorrespondenceEstimation)并设置使用法线作为特征(但通常这个类只使用坐标)。 另外,在引用[5]中提到了基于ISS和FPFH提取特征点,但用户现在需要的是基于法线的匹配点对,所以我们可以专注于法线匹配。 步骤: 1. 计算源点云和目标点云的法线(如果还没有计算的话)。 2. 选择一个基于法线的对应点估计方法(例如NormalShooting或BackProjection)。 3. 设置输入源点云和目标点云(以及它们的法线)。 4. 设置搜索方法(例如kdtree)。 5. 计算对应点。 下面是一个使用`pcl::registration::CorrespondenceEstimationNormalShooting`的示例代码: 注意:在使用之前,确保已经计算了法线。 代码示例: ```cpp #include <pcl/registration/correspondence_estimation_normal_shooting.h> #include <pcl/features/normal_3d.h> // 假设已经有点云src和tgt(PointCloud<PointXYZ>::Ptr类型) pcl::PointCloud<pcl::PointXYZ>::Ptr src(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr tgt(new pcl::PointCloud<pcl::PointXYZ>); // 计算法线(分别计算源点云和目标点云的法线) pcl::PointCloud<pcl::Normal>::Ptr src_normals(new pcl::PointCloud<pcl::Normal>); pcl::PointCloud<pcl::Normal>::Ptr tgt_normals(new pcl::PointCloud<pcl::Normal>); // 计算法线的步骤(这里省略,可以使用NormalEstimation) // 创建对应点估计对象 pcl::registration::CorrespondenceEstimationNormalShooting<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> corr_est; // 设置源点云(包括点) corr_est.setInputSource(src); // 设置源点云的法线 corr_est.setSourceNormals(src_normals); // 设置目标点云 corr_est.setInputTarget(tgt); // 设置搜索方法(默认为KdTree,也可以自定义) // 可以设置k近邻搜索的数量 // corr_est.setKSearch(10); // 如果不设置,则使用默认值 // 计算对应点 pcl::Correspondences correspondences; corr_est.determineCorrespondences(correspondences); // 现在correspondences中存储了估计的对应点对 ``` 另一种方法是使用`CorrespondenceEstimationBackProjection`,它通过反向投影并考虑法线方向的一致性来寻找对应点,对噪声和异常值更鲁棒。 代码示例: ```cpp #include <pcl/registration/correspondence_estimation_backprojection.h> pcl::registration::CorrespondenceEstimationBackProjection<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> corr_est_bp; corr_est_bp.setInputSource(src); corr_est_bp.setSourceNormals(src_normals); corr_est_bp.setInputTarget(tgt); // 目标点云的法线也需要,因为反向投影会用到 corr_est_bp.setTargetNormals(tgt_normals); pcl::Correspondences correspondences_bp; corr_est_bp.determineCorrespondences(correspondences_bp); ``` 注意:这些方法都需要点云具有法线信息。在计算法线时,通常需要设置搜索半径或近邻数。 用户可能需要根据具体场景调整参数,例如法线估计的半径、对应点估计时的近邻数等。 此外,引用[3]中提到了点云配准的一些其他步骤(如关键点提取、特征描述子计算),但用户的问题仅涉及匹配点对查找,所以这里没有涉及特征描述子(如FPFH、SHOT等)的计算。如果用户需要更稳健的匹配,可以结合特征描述子进行匹配(如使用`pcl::registration::CorrespondenceEstimation`配合特征描述子)。 但根据用户要求,我们只讨论基于法线的匹配点对查找。 因此,我们提供了两种基于法线的对应点估计方法:NormalShooting和BackProjection,并给出了代码框架。 接下来,生成相关问题。</think>### 在PCL中基于法线信息查找匹配点对 在PCL中,基于法线信息查找匹配点对主要通过`pcl::registration::CorrespondenceEstimationNormalShooting`类实现。该方法利用点云的法线方向进行对应点搜索,比单纯基于坐标的匹配更鲁棒,尤其适用于部分重叠或存在噪声的点云配准场景[^4]。 #### 核心步骤 1. **法线计算** 使用`pcl::NormalEstimation`计算源点云和目标点云的法线: ```cpp pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> norm_est; norm_est.setInputCloud(source_cloud); norm_est.setSearchMethod(search_tree); norm_est.setRadiusSearch(0.05); // 法线估计半径 norm_est.compute(*source_normals); ``` 2. **法线投影匹配** 通过法线方向投影建立对应关系: ```cpp pcl::registration::CorrespondenceEstimationNormalShooting<pcl::PointXYZ, pcl::PointXYZ, pcl::Normal> corr_est; corr_est.setInputSource(source_cloud); corr_est.setSourceNormals(source_normals); corr_est.setInputTarget(target_cloud); corr_est.setKSearch(10); // 搜索近邻点数 corr_est.determineCorrespondences(*correspondences); ``` #### 关键参数说明 - **法线一致性约束**:可通过`setNormalDistanceWeight()`设置法线角度差异的权重,值越大对法线方向一致性要求越严格。 - **搜索策略**:支持`KdTree`或`Octree`加速搜索,需提前初始化: ```cpp pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); corr_est.setSearchMethodTarget(tree); ``` #### 优化建议 1. **法线平滑处理**:对噪声较大的点云,使用`pcl::MovingLeastSquares`进行平滑处理后再计算法线[^3]。 2. **异常点过滤**:结合`pcl::registration::CorrespondenceRejectorSampleConsensus`移除错误匹配点对[^5]。 3. **多特征融合**:若需更高精度,可结合FPFH等特征描述子进行混合匹配[^1]。 > **示例输出**:匹配结果存储在`pcl::Correspondences`对象中,每个对应点包含源点索引(`index_query`)和目标点索引(`index_match`)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值