PCL 点云半径滤波

news2024/10/4 7:00:11

目录

一、概述

1.1原理

1.2实现步骤

1.3应用场景

二、代码实现

2.1关键函数

2.1.1 半径滤波实现

2.1.2 可视化函数

2.2完整代码

三、实现效果


PCL点云算法汇总及实战案例汇总的目录地址链接:

PCL点云算法与项目实战案例汇总(长期更新)


一、概述

        半径滤波(Radius Outlier Removal) 是一种点云滤波技术,主要用于去除孤立点或稀疏点。半径滤波通过检查每个点的邻域内的点的数量,来判断该点是否保留。如果某个点在给定半径内的邻居点数量低于用户定义的阈值,则该点会被认为是离群点并被删除。

1.1原理

        半径滤波的基本思想是:对于点云中的每个点,检查在一定半径内的邻居点数量。假如某点的邻居数量低于预定阈值,则认为该点为噪声点或异常点,将其剔除。半径和邻居数量这两个参数决定了滤波的效果。

1.2实现步骤

  1. 读取点云数据。
  2. 设置半径滤波的参数,包括搜索半径和最小邻居数。
  3. 应用半径滤波,生成过滤后的点云。
  4. 可视化原始点云和过滤后的点云。

1.3应用场景

  1. 去除噪声点:在点云数据采集中,由于传感器噪声、环境干扰等原因,可能会产生一些离群点,半径滤波可以有效去除这些噪声点。
  2. 稀疏点云处理:在处理稀疏点云时,半径滤波可以剔除那些孤立存在的点。
  3. 数据预处理:为点云的其他处理任务提供更干净的输入数据。

二、代码实现

2.1关键函数

2.1.1 半径滤波实现

通过设置邻域半径和最小邻居数量,应用半径滤波。

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>

// 半径滤波函数
pcl::PointCloud<pcl::PointXYZ>::Ptr radiusOutlierRemoval(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,  // 输入点云
    float radius,                               // 半径大小
    int min_neighbors                           // 最小邻居数量
)
{
    // 创建半径滤波对象,并设置参数
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
    outrem.setInputCloud(cloud);                // 设置输入点云
    outrem.setRadiusSearch(radius);             // 设置半径
    outrem.setMinNeighborsInRadius(min_neighbors);  // 设置最小邻居数

    // 滤波后的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    outrem.filter(*filtered_cloud);  // 应用滤波

    return filtered_cloud;  // 返回过滤后的点云
}

2.1.2 可视化函数

使用 PCL 可视化库展示原始点云和半径滤波后的点云。

#include <pcl/visualization/pcl_visualizer.h>

// 可视化原始点云和过滤后的点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,          // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud  // 过滤后的点云
)
{
    // 创建可视化器
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Radius Outlier Removal Viewer"));

    // 创建视口1,显示原始点云
    int vp_1;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);          // 创建左侧窗口
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);           // 设置白色背景
    viewer->addText("Raw Point Clouds", 10, 10, "v1_text", vp_1);  // 添加标题

    // 设置原始点云的颜色为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color_handler, "original_cloud", vp_1);  // 添加原始点云

    // 创建视口2,显示过滤后的点云
    int vp_2;
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);          // 创建右侧窗口
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);        // 设置浅灰色背景
    viewer->addText("Filtered Point Clouds", 10, 10, "v2_text", vp_2);  // 添加标题

    // 设置过滤后的点云的颜色为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_cloud_color_handler(filtered_cloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud<pcl::PointXYZ>(filtered_cloud, filtered_cloud_color_handler, "filtered_cloud", vp_2);  // 添加过滤后的点云

    // 设置点的大小(可选)
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", vp_1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "filtered_cloud", vp_2);

    // 启动可视化循环
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);  // 刷新可视化器
    }
}

2.2完整代码

// C++头文件
#include <iostream>
// PCL头文件
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>  // 半径滤波
#include <pcl/visualization/pcl_visualizer.h>

// 半径滤波函数
pcl::PointCloud<pcl::PointXYZ>::Ptr radiusOutlierRemoval(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,  // 输入点云
    float radius,                               // 半径大小
    int min_neighbors                           // 最小邻居数量
)
{
    // 创建半径滤波对象,并设置参数
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
    outrem.setInputCloud(cloud);                // 设置输入点云
    outrem.setRadiusSearch(radius);             // 设置半径
    outrem.setMinNeighborsInRadius(min_neighbors);  // 设置最小邻居数

    // 滤波后的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    outrem.filter(*filtered_cloud);  // 应用滤波

    return filtered_cloud;  // 返回过滤后的点云
}

// 可视化原始点云和过滤后的点云
void visualizePointClouds(
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,          // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud  // 过滤后的点云
)
{
    // 创建可视化器
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Radius Outlier Removal Viewer"));

    // 创建视口1,显示原始点云
    int vp_1;
    viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);          // 创建左侧窗口
    viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1);           // 设置白色背景
    viewer->addText("Raw Point Clouds", 10, 10, "v1_text", vp_1);  // 添加标题

    // 设置原始点云的颜色为红色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 255, 0, 0);  // 红色
    viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color_handler, "original_cloud", vp_1);  // 添加原始点云

    // 创建视口2,显示过滤后的点云
    int vp_2;
    viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);          // 创建右侧窗口
    viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2);        // 设置浅灰色背景
    viewer->addText("Filtered Point Clouds", 10, 10, "v2_text", vp_2);  // 添加标题

    // 设置过滤后的点云的颜色为绿色
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_cloud_color_handler(filtered_cloud, 0, 255, 0);  // 绿色
    viewer->addPointCloud<pcl::PointXYZ>(filtered_cloud, filtered_cloud_color_handler, "filtered_cloud", vp_2);  // 添加过滤后的点云

    // 设置点的大小(可选)
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", vp_1);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "filtered_cloud", vp_2);

    // 启动可视化循环
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);  // 刷新可视化器
    }
}

int main(int argc, char** argv)
{
    // ------------------------------读取点云数据---------------------------------
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile("ro_bunny.pcd", *cloud) < 0)
    {
        PCL_ERROR("Could not read file\n");
        return (-1);  // 返回错误
    }

    // -------------------------------半径滤波---------------------------------
    float radius = 0.002;   // 设置搜索半径
    int min_neighbors = 6;  // 设置最小邻居数
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud = radiusOutlierRemoval(cloud, radius, min_neighbors);  // 应用半径滤波

    // ------------------------------可视化原始点云和过滤后的点云---------------------------------
    visualizePointClouds(cloud, filtered_cloud);  // 调用可视化函数

    return 0;
}

三、实现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2187572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL,如何选择?

深耕AI&#xff1a;互联网行业 算法研发工程师 ​ 目录 MFC ActiveX 控件 控件的类型 标准控件 自定义控件 ActiveX控件 MFC ActiveX控件 标准/自定义控件 MFC ActiveX控件分类 3种MFC如何选择&#xff1f; MFC ActiveX控件 MFC 应用程序 MFC DLL 总结 举例说明…

【JAVA开源】基于Vue和SpringBoot的周边产品销售网站

本文项目编号 T 061 &#xff0c;文末自助获取源码 \color{red}{T061&#xff0c;文末自助获取源码} T061&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

申请免费或试用VPS服务

申请免费或试用VPS服务 有时候我们特别希望能够找到一台像 Oracle Cloud 一样的永久免费 VPS&#xff08;需要满足一定的条件&#xff09;&#xff0c;可相对于其它厂商申请相对比较难&#xff0c;可能需要多次申请才能得到。其实&#xff0c;除了 Oracle Cloud 之外&#xff0…

阿里云对象存储OSS 速学

目录 1.创建一个Bucket 2.创建密钥AccessKey 3.在文档中心打开阿里云对象存储OSS 4.参考上传文件示例 以官网的文档为主&#xff0c;我的文章教学为辅 官网有详细的视频介绍&#xff1a; OSS快速入门_对象存储(OSS)-阿里云帮助中心 (aliyun.com)https://help.aliyun.com/…

Linux: network: 典型网络延迟图,CPU导致;

接上回说&#xff0c;https://mzhan017.blog.csdn.net/article/details/142689870&#xff1b; 其中在debug的过程中&#xff0c;看到下面这个IO图&#xff0c;这个图比较经典&#xff0c;是一个典型的网络延迟图&#xff0c;可用作为分析问题的一个参考。 如下图&#xff1a;黑…

C++ | Leetcode C++题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; class Solution { public:int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {unordered_map<int, int> countAB;for (int u: A) {for (int v: B) {count…

ZYNQ: GPIO 之 EMIO 按键控制 LED 实验

GPIO 之 EMIO 按键控制 LED 实验目的 使用启明星 ZYNQ 底板上的两个用户按键分别控制 PS 端两个 LED 的亮灭 其中一个按键 PL_KEY0 连接到了 PL 端&#xff0c;需要通过 EMIO 进行扩展&#xff0c;另外一个按键是底板上 PS 端的用户按键PS_KEY0&#xff0c;这两个按键分别控制…

堆的向上和向下调整

堆的物理结构和逻辑结构是什么&#xff1f; 堆如何插入数据和删除数据&#xff1f;为什么&#xff1f; 向上调整和向下调整的要求是啥&#xff1f; 文中不理解的可以先看堆的代码和基础知识-CSDN博客 也欢迎评论区一起讨论 1.堆的物理结构和逻辑结构 我们的堆是用数组实…

计算机毕业设计 视频点播系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【AI知识点】维度灾难(curse of dimensionality)

维度灾难&#xff08;curse of dimensionality&#xff09; 是指在处理高维数据时&#xff0c;随着维度的增加&#xff0c;数据的性质和空间结构变得越来越复杂&#xff0c;导致许多常见的算法和技术在高维空间中效率低下或效果变差的问题。 这个概念最早是由Richard Bellman在…

RabbitMQ篇(基本介绍)

目录 一、MQ 1. 什么是MQ 2. 为什么要用MQ【业务场景】 2.1. 异步 2.2. 应用解耦 2.3. 流量削峰 3. MQ的分类 &#xff08;1&#xff09;ActiveMQ &#xff08;2&#xff09;Kafka &#xff08;3&#xff09;RocketMQ &#xff08;4&#xff09;RabbitMQ 4. MQ 的选…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02 1. APM: Large Language Model Agent-based Asset Pricing Models Authors: Junyan Cheng, Peter Chin https://arxiv.org/abs/2409.17266 APM: 基于大型语言模型的代理资产定价模型&#xff08;LLM Agent-b…

2、项目配置设计(上)

文章目录 前言一、配置文件功能需求二、web工程设计思路三、Config实现思路 前言 配置文件作用&#xff1a;把需要经常修改的参数&#xff0c;从代码中分离出来,单独管理&#xff0c;方便后期维护。 开发一个web应用&#xff0c;肯定需要一些基础性的配置信息&#xff0c;这些信…

骨架屏 (懒加载优化)

骨架屏 &#xff08;懒加载优化&#xff09; 即便通过 Webpack 的按需加载、CDN 静态资源缓存 和 代码分割 等技术来减少首屏的代码体积&#xff0c;首屏加载时的白屏时间&#xff08;也称为首屏等待时间&#xff09;仍然可能存在&#xff0c;尤其在网络条件较差或页面内容复杂…

【设计模式-解释模式】

定义 解释器模式是一种行为设计模式&#xff0c;用于定义一种语言的文法&#xff0c;并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类&#xff0c;使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…

基于Springboot vue应急物资供应管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

【硬件模块】HC-SR04超声波模块

HC-SR04超声波模块实物图 工作参数 探测距离&#xff1a;2~600cm 探测精度&#xff1a;0.1cm1% 感应角度&#xff1a;<15 输出方式&#xff1a;GPIO 工作电压&#xff1a;DC 3~5.5V 工作电流&#xff1a;5.3mA 工作温度&#xff1a;-40~85℃ 引脚接线 HC-SR04MCU备注VC…

Golang | Leetcode Golang题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; func fourSumCount(a, b, c, d []int) (ans int) {countAB : map[int]int{}for _, v : range a {for _, w : range b {countAB[vw]}}for _, v : range c {for _, w : range d {ans countAB[-v-w]}}return }

04-SpringBootWeb案例(下)

3. 员工管理 完成了部门管理的功能开发之后&#xff0c;我们进入到下一环节员工管理功能的开发。 基于以上原型&#xff0c;我们可以把员工管理功能分为&#xff1a; 分页查询&#xff08;今天完成&#xff09;带条件的分页查询&#xff08;今天完成&#xff09;删除员工&am…

Pikachu-Sql Inject-数字型注入(GET)

一、、破解 SQL 查询语句中的字段数 ?id1 order by 3 -- // -- 是注释&#xff0c; 加号 在MySQL中会转成空格 order by 1 &#xff0c;by 数字几&#xff0c;就是按照第几列进行排序&#xff1b;如果没有这一行&#xff0c;则报错 如&#xff1a;以下语句&#xff0c;根据…