PCL 基于距离阈值去除错误对应关系(永久免费版)
目录
- 一、概述
- 1.1 原理
- 1.2 实现步骤
- 1.3应用场景
- 二、关键函数
- 2.1 获取初始点对
- 2.2 基于距离的对应关系筛选函数
- 2.3 可视化
- 三、完整代码
- 四、结果展示
即日起,付费专栏所有内容将以永久免费形式陆续进行发表!!!
一、概述
在3D点云的配准过程中,我们通常会找到源点云和目标点云之间的对应点对。然而,这些对应点对可能包含一些错误的匹配关系。为了提升配准的精度,必须通过某些策略来剔除这些错误的对应点。本文将介绍一种基于距离阈值的错误对应关系剔除方法,实现对应点对的距离进行筛选,并移除那些不符合阈值要求的点对。
1.1 原理
在点云配准中,通常通过某种策略找到两个点云之间的初始对应点对。这些对应点对可能包含一些错误的匹配,比如距离过远的点对。通过设定一个合理的距离阈值,剔除那些不符合要求的点对,可以大大提高配准的精度。这里我们使用PCL中的
CorrespondenceRejectorDistance类对初始的对应关系进行筛选,保留距离在指定阈值内的点对。
1.2 实现步骤
加载源点云和目标点云。
使用PCL的CorrespondenceEstimation类获取初始的点对匹配关系。
使用CorrespondenceRejectorDistance类基于距离阈值筛选对应点对。
可视化筛选前后的点对匹配关系,展示最终的结果
1.3应用场景
- 多视角点云的精确配准。
- 机器人SLAM中的环境建模。
- 自动驾驶中点云数据的对齐与去噪。
二、关键函数
2.1 获取初始点对
该函数使用CorrespondenceEstimation类来计算源点云与目标点云之间的初始匹配点对。
// 获取初始对应点对
void getCorrespondencesByDistance(const pcl::PointCloud<pcl::PointXYZ>::Ptr& source,const pcl::PointCloud<pcl::PointXYZ>::Ptr& target,pcl::CorrespondencesPtr& correspondences)
{// 创建对应估计对象pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;corr_est.setInputSource(source); // 设置输入源点云corr_est.setInputTarget(target); // 设置输入目标点云// 获取源点云和目标点云的初始对应点对corr_est.determineCorrespondences(*correspondences);
}
2.2 基于距离的对应关系筛选函数
该函数使用CorrespondenceRejectorDistance类来剔除距离过大的对应点对。
// 基于距离的对应关系筛选
void rejCorrespondencesByDistance(const pcl::CorrespondencesPtr& correspondences,pcl::CorrespondencesPtr& correspondences_result_rej_dist,double max_distance)
{// 使用CorrespondenceRejectorDistance类剔除距离过大的点对pcl::registration::CorrespondenceRejectorDistance corr_rej_dist;corr_rej_dist.setInputCorrespondences(correspondences); // 设置输入的对应关系corr_rej_dist.setMaximumDistance(max_distance); // 设置最大距离阈值corr_rej_dist.getCorrespondences(*correspondences_result_rej_dist); // 获取剔除后的对应关系
}
2.3 可视化
// 可视化点云及对应点对
void visualizeRegistrationResult(const pcl::PointCloud<pcl::PointXYZ>::Ptr& source,const pcl::PointCloud<pcl::PointXYZ>::Ptr& target,const pcl::CorrespondencesPtr& correspondences_result_rej_dist)
{// 创建PCLVisualizer对象boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("配准结果"));viewer->setBackgroundColor(0, 0, 0); // 设置背景颜色为黑色// 源点云着色为绿色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color(source, 0, 255, 0);viewer->addPointCloud<pcl::PointXYZ>(source, source_color, "source cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "source cloud");// 目标点云着色为红色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(target, 255, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(target, target_color, "target cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target cloud");// 添加对应点对的可视化viewer->addCorrespondences<pcl::PointXYZ>(source, target, *correspondences_result_rej_dist, "correspondence");// 开启渲染循环,直到窗口关闭while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}
}
三、完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/registration/correspondence_estimation.h> // 获取对应关系的基类
#include <pcl/registration/correspondence_rejection_distance.h> // 使用距离剔除的类using namespace std;// 获取初始对应点对
void getCorrespondences(const pcl::PointCloud<pcl::PointXYZ>::Ptr& source,const pcl::PointCloud<pcl::PointXYZ>::Ptr& target,pcl::CorrespondencesPtr& correspondences)
{pcl::registration::CorrespondenceEstimation<pcl::PointXYZ, pcl::PointXYZ> corr_est;corr_est.setInputSource(source); // 设置源点云corr_est.setInputTarget(target); // 设置目标点云corr_est.determineCorrespondences(*correspondences); // 获取初始匹配点对
}// 基于距离的对应关系筛选
void rejCorrespondencesByDistance(const pcl::CorrespondencesPtr& correspondences,pcl::CorrespondencesPtr& correspondences_result_rej_dist,double max_distance)
{// 使用CorrespondenceRejectorDistance类剔除距离过大的点对pcl::registration::CorrespondenceRejectorDistance corr_rej_dist;corr_rej_dist.setInputCorrespondences(correspondences); // 设置输入的对应关系corr_rej_dist.setMaximumDistance(max_distance); // 设置最大距离阈值corr_rej_dist.getCorrespondences(*correspondences_result_rej_dist); // 获取剔除后的对应关系
}// 可视化点云及其对应关系
void visualizeCorrespondencesResult(const pcl::PointCloud<pcl::PointXYZ>::Ptr& source,const pcl::PointCloud<pcl::PointXYZ>::Ptr& target,const pcl::CorrespondencesPtr& correspondences)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer(u8"基于距离的对应关系"));viewer->setBackgroundColor(0, 0, 0); // 设置背景颜色为黑色// 为目标点云设置红色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> target_color(target, 255, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(target, target_color, "target cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target cloud");// 为源点云设置绿色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source_color(source, 0, 255, 0);viewer->addPointCloud<pcl::PointXYZ>(source, source_color, "source cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "source cloud");// 可视化对应关系viewer->addCorrespondences<pcl::PointXYZ>(source, target, *correspondences, "correspondence");// 开启渲染循环,直到窗口关闭while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}
}int main(int argc, char** argv)
{// ---------------------------------加载源点云----------------------------------pcl::PointCloud<pcl::PointXYZ>::Ptr source(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>("bun000.pcd", *source) == -1){PCL_ERROR("读取源标点云失败 \n");return (-1);}cout << "从源点云中读取 " << source->size() << " 个点" << endl;// ---------------------------------加载目标云---------------------------------pcl::PointCloud<pcl::PointXYZ>::Ptr target(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>("bun045.pcd", *target) == -1){PCL_ERROR("读取目标点云失败 \n");return (-1);}cout << "从目标点云中读取 " << target->size() << " 个点" << endl;// 2. 获取初始对应点对pcl::CorrespondencesPtr correspondences(new pcl::Correspondences);getCorrespondences(source, target, correspondences);// 3. 基于距离剔除错误对应点对,并获取距离pcl::CorrespondencesPtr correspondences_result_rej(new pcl::Correspondences);rejCorrespondencesByDistance(correspondences, correspondences_result_rej, 0.2);cout << "初始对应点对数量: " << correspondences->size() << endl;cout << "基于中值距离剔除后剩余: " << correspondences_result_rej->size() << endl;// 4. 可视化结果visualizeCorrespondencesResult(source, target, correspondences_result_rej);return 0;
}
四、结果展示
从源点云中读取 40256 个点
从目标点云中读取 40097 个点
初始对应点对数量: 40256
基于距离阈值剔除后剩余: 40256

相关文章:
PCL 基于距离阈值去除错误对应关系(永久免费版)
目录 一、概述1.1 原理1.2 实现步骤1.3应用场景 二、关键函数2.1 获取初始点对2.2 基于距离的对应关系筛选函数2.3 可视化 三、完整代码四、结果展示 即日起,付费专栏所有内容将以永久免费形式陆续进行发表!!! 一、概述 在3D点云的…...
DirectX 11 和 Direct3D 11 的关系
以下是对两者的详细比较: DirectX 11 DirectX 11是微软的一项技术,为高性能游戏和复杂图形程序制定了标准。它是DirectX系列的一个版本,引入了多项创新功能,如硬件加速的Tessellation(细分曲面技术)、多线…...
什么是SCRM?为什么企业要做SCRM?
很多人都知道CRM是客户关系管理系统,而SCRM又是什么呢? 今天我就给大家用一文讲清SCRM的那些事,本文包括:SCRM 的定义与内涵,与传统 CRM 的区别;通过案例阐述其重要性及作用,如适应消费模式转变…...
类间方差,分割地物
类间方差(Inter-class Variance)是用于图像分割中的一种统计量,特别是在使用Otsu方法进行阈值选择时。它衡量的是分割后两个类别(通常是前景和背景)之间的分离程度。类间方差越大,说明两个类别之间的差异越…...
基于微博评论的自然语言处理情感分析
目录 一、项目概述 二、需要解决的问题 三、数据预处理 1、词汇表构建(vocab_creat.py) 2、数据集加载(load_dataset.py) 四、模型构建(TextRNN.py) 1、嵌入层(Embedding Layerÿ…...
MFEM( Modular Finite Element Methods)是一个灵活的、可扩展的、开源的有限元库
MFEM( Modular Finite Element Methods )是一个灵活的、可扩展的、开源的有限元库,主要用于求解偏微分方程(PDE)问题。MFEM的目标是通过模块化设计和强大的抽象能力,简化有限元方法的使用,并支持高效的并行计算,尤其是在复杂的几何形状和自适应网格细化的情况下。 核…...
在VMware上创建虚拟机以及安装Linux操作系统,使用ssh进行远程连接VMware安装注意点 (包含 v1,v8两张网卡如果没有的解决办法)
一,VMware上创建虚拟机 1.VMware下载 1)点击VMware官网进入官网 网址:VMware by Broadcom - Cloud Computing for the EnterpriseOptimize cloud infrastructure with VMware for app platforms, private cloud, edge, networking, and security.https…...
关于vue3中如何实现多个v-model的自定义组件
实现自定义组件<User v-model"userInfo" v-model:gender"gender"></User> User组件中更改数据可以同步更改父组件中的数据: 1 父组件: <User v-model"userInfo" v-model:gender"gender">&…...
【STM32项目_2_基于STM32的宠物喂食系统】
摘要:本文介绍一款基于 STM32 的宠物喂食系统资源。该系统以 STM32 为核心,集成多种传感器与设备,涵盖 DHT11、HX711、减速马达及 ESP8266 模块,具备环境监测、精准喂食、网络连接及数据存储功能。 🔜🔜&am…...
商场楼宇室内导航系统
商场楼宇室内导航系统 本文所涉及所有资源均在传知代码平台可获取 文章目录 商场楼宇室内导航系统效果图导航效果图查看信息数据加载加载模型模型选型处理楼层模型绑定店铺创建店铺名称动态显示隐藏2d元素空气墙查看信息楼梯导航效果图 导航效果图 查看信息 数据加载 因为是一…...
2025全网最全计算机毕业设计选题推荐:计算机毕设选题指导及避坑指南√
博主介绍:✌全网粉丝50W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围:SpringBoot、Vue、SSM、HLM…...
Vision China 2024 | 移远通信以一体化的AI训练及部署能力,引领3C电子制造智能升级
10月14日,由机器视觉产业联盟(CMVU)主办的中国机器视觉展(Vision China)在深圳国际会展中心盛大开幕。作为全球领先的物联网整体解决方案供应商,移远通信应邀参加展会首日举办的“智造引领数质并进”3C电子制造自动化与数字化论坛。 论坛上,移…...
浏览器播放rtsp视频流解决方案
方案一: html5 websocket_rtsp_proxy 实现视频流直播 实现原理 实现步骤 服务器安装streamedian服务器 客户端通过video标签播放 <video id"test_video" controls autoplay></video><script src"free.player.1.8.4.js"></script&g…...
Ubuntu下查看指定文件大小
Ubuntu下查看指定文件大小 方法一:查看指定文件夹的总大小方法二:查看文件夹内各个子文件夹的大小方法三:查看指定深度的子文件夹大小方法四:使用ls命令查看单个文件的大小注意事项 在Ubuntu中查看指定文件夹的大小,你…...
【南开X上海交大】OPUS:效率显著提升的OCC网络
1. 摘要 占据预测任务旨在预测体素化的3D环境中的占据状态,在自动驾驶领域中迅速获得了关注。主流的占据预测方法首先将3D环境离散化为体素网格,然后在这些密集网格上执行分类。然而,样本数据分析显示,大多数体素实际上是未占据的…...
SqlUtils 使用
一、前言 随着 Solon 3.0 版本发布,新添加的 SqlUtils 接口,用于操作数据库,SqlUtils 是对 Jdbc 原始接口的封装。适合 SQL 极少或较复杂,或者 ORM 不适合的场景使用。 二、SqlUtils 使用 1、引入依赖 <dependency><…...
平面声波——一维Helmhotz波动方程
平面声波的一维Helmholtz波动方程是一种简化的声波传播模型,适用于在一维空间中传播的声波。 声波的基本物理过程---傅里叶变换---Helmholtz方程 一、声波的基本波动方程 在无源、无耗散、均匀介质中的一维声波的波动方程为: 其中: 表示位…...
深度学习 简易环境安装(不含Anaconda)
在Windows上安装深度学习环境而不使用Anaconda,下面是一个基于pip的安装指南: 1. 安装Python 确保你已经安装了Python。可以从Python官网下载Python,并在安装时勾选“Add Python to PATH”选项。 注意,Python 不要安装最新版的…...
Java缓存技术(java内置缓存,redis,Ehcache,Caffeine的基本使用方法及其介绍)
目录 摘要 1. Java缓存技术概述 1.1定义 1.2 优势 1.3 应用场景 2. Java中的内置缓存实现 2.1 通过通过HashMap和ConcurrentHashMap实现缓存 3. Java缓存框架 3.1 Redis 3.1.1 redis的简介 3.1.4 Redis的工作原理 3.1.5 总结 3.2 Ehcache 3.2.1 Eh…...
YoloV9改进策略:主干网络改进|DeBiFormer,可变形双级路由注意力|全网首发
摘要 在目标检测领域,YoloV9以其高效和准确的性能而闻名。然而,为了进一步提升其检测能力,我们引入了DeBiFormer作为YoloV9的主干网络。这个主干网络的计算量比较大,不过,上篇双级路由注意力的论文受到很大的关注,所以我也将这篇论文中的主干网络用来改进YoloV9,卡多的…...
AssetRipper终极指南:轻松提取Unity游戏资源的完整教程
AssetRipper终极指南:轻松提取Unity游戏资源的完整教程 【免费下载链接】AssetRipper GUI Application to work with engine assets, asset bundles, and serialized files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper 还在为无法获取Uni…...
3分钟破解百度网盘提取码难题:智能解析工具完全指南
3分钟破解百度网盘提取码难题:智能解析工具完全指南 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘加密资源的提取码而烦恼吗?每次点击分享链接却卡在"请输入提取码"的弹窗前…...
3个高效步骤解决猫抓扩展资源嗅探故障
3个高效步骤解决猫抓扩展资源嗅探故障 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 猫抓(Cat Catch)作为一款浏览器资源嗅…...
IntelliJ IDEA开发Qwen3-TTS-12Hz-1.7B-CustomVoice插件教程
IntelliJ IDEA开发Qwen3-TTS-12Hz-1.7B-CustomVoice插件教程 1. 引言 你是不是经常需要在开发过程中生成语音内容?比如给应用添加语音提示、制作有声说明文档,或者只是想给枯燥的编程生活加点声音乐趣?今天我要带你用IntelliJ IDEA开发一个…...
台式电脑怎么连接打印机 4种方法详细教程
台式电脑连接打印机的方法多种多样,具体选择取决于打印机类型和使用环境。合理选择连接方式,不仅能提高打印效率,还能减少后续使用中的故障问题。下面将详细介绍几种常见的连接方法及操作步骤。 一、通过USB数据线连接 这种方式最为直接常见…...
万象视界灵坛保姆级教程:Bright-Pixel UI下上传图片+输入神谕标签全流程
万象视界灵坛保姆级教程:Bright-Pixel UI下上传图片输入神谕标签全流程 1. 教程概述 万象视界灵坛是一款基于OpenAI CLIP技术的高级多模态智能感知平台,通过独特的Bright-Pixel UI设计,将复杂的图像语义分析转化为直观有趣的交互体验。本教…...
【ESP32-S3】通过ROS2使用YDLIDAR X2进行SLAM、自主导航方案选择
通过ROS2使用YDLIDAR X2进行SLAM、自主导航方案选择背景一、方案总览(两种主流实现)方案A:纯透传(最简,推荐入门)方案B:Micro-ROS(标准ROS 2架构,适合完整导航࿰…...
SAP 生产订单批量创建与下达实战:基于 BAPI_PRODORD_CREATE 的自动化方案
1. 为什么需要批量创建生产订单? 在制造业的实际业务场景中,生产计划部门经常需要根据销售订单、预测数据或库存情况,一次性生成大量生产订单。想象一下,一个汽车零部件工厂每月要处理上千个零部件的生产计划,如果每个…...
避坑指南:在Windows/Mac上从零部署Grounding DINO和SAM的完整流程(含模型下载、环境配置)
避坑指南:在Windows/Mac上从零部署Grounding DINO和SAM的完整流程 部署多模态AI模型时,90%的失败发生在环境配置阶段。本文将手把手带你避开所有常见陷阱,从模型下载到最终运行,提供双系统兼容的解决方案。不同于常规教程…...
OpenClaw跨平台实战:千问3.5-9B在mac与Windows的自动化对比
OpenClaw跨平台实战:千问3.5-9B在mac与Windows的自动化对比 1. 为什么需要跨平台对比 去年我在团队内部推广自动化工具时,遇到一个典型问题:同事们的开发环境分散在macOS和Windows两大平台。当我们尝试用OpenClaw千问3.5-9B构建统一自动化流…...
