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,卡多的…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...

spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...