PCL 实现K近邻查找匹配点对【2024最新版】

264 篇文章 ¥19.90 ¥99.00
本文介绍了基于PCL库中的KdTreeFLANN算法,实现K近邻查找匹配点对的方法。重点讲解了算法依据,即当K=1时,如何寻找最接近的点,并给出了相应的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

本文由CSDN点云侠原创,原文链接,首发于:2020年7月25日。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的抄袭狗。

博客长期更新,本文最近一次更新时间为:2024年8月21日。

一、算法依据

  由KDTree 的算法原理可知, 当邻域点集中点数k为1 时, 搜寻点与邻域点间建立一一映射关系。此时, 搜索到的邻域点是搜寻点与邻域点集中距离最小的点。

KD树的一个应用:pcl::KdTreeFLANN

二、代码实现

1、原始版本

<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
发出的红包

打赏作者

点云侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值