pcl之滤波器(三)

news2024/12/25 12:16:53

在这里插入图片描述

pcl滤波器

pcl一共是有十二个主要模块,详细了解可以查看官网。https://pcl.readthedocs.io/projects/tutorials/en/latest/#basic-usage

今天学习一下pcl的滤波器模块。

滤波器模块,官网一共是提供了6个例程,今天看第五个、第六个。

从一个点云中提取索引

在本例程中,将学习如何使用ExtractIndices过滤器根据分割算法输出的索引从点云中提取点的子集。

感兴趣的可以看一下YouTube演示视频
https://youtu.be/ZTK7NR1Xx4c

作为演示的pcd文件地址,需要自取
https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

看代码

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>  // 从一个点云中提取索引 

int
main (int argc, char** argv)
{  

  /**********************************************************************************************************
   从输入的.PCD 文件载入数据后,创建一个VoxelGrid滤波器对数据进行下采样,在这里进行下才样是为了加速处理过程,
   越少的点意味着分割循环中处理起来越快
   **********************************************************************************************************/

  pcl::PCLPointCloud2::Ptr cloud_blob (new pcl::PCLPointCloud2), cloud_filtered_blob (new pcl::PCLPointCloud2);//申明滤波前后的点云
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>), cloud_p (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);

  // 读取PCD文件
  pcl::PCDReader reader;
  reader.read ("../table_scene_lms400.pcd", *cloud_blob);
   //统计滤波前的点云个数
  std::cerr << "PointCloud before filtering: " << cloud_blob->width * cloud_blob->height << " data points." << std::endl;

  // 创建体素栅格下采样: 下采样的大小为1cm
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;  //体素栅格下采样对象
  sor.setInputCloud (cloud_blob);             //原始点云
  sor.setLeafSize (0.01f, 0.01f, 0.01f);    // 设置采样体素大小
  sor.filter (*cloud_filtered_blob);        //保存

  // 转换为模板点云
  pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points." << std::endl;

  // 保存下采样后的点云
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("../table_scene_lms400_downsampled.pcd", *cloud_filtered, false);
  
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());   
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());

  pcl::SACSegmentation<pcl::PointXYZ> seg;               //创建分割对象
  seg.setOptimizeCoefficients (true);                    //设置对估计模型参数进行优化处理
  seg.setModelType (pcl::SACMODEL_PLANE);                //设置分割模型类别
  seg.setMethodType (pcl::SAC_RANSAC);                   //设置用哪个随机参数估计方法
  seg.setMaxIterations (1000);                            //设置最大迭代次数
  seg.setDistanceThreshold (0.01);                      //判断是否为模型内点的距离阀值

  // 设置ExtractIndices的实际参数
  pcl::ExtractIndices<pcl::PointXYZ> extract;        //创建点云提取对象

  int i = 0, nr_points = (int) cloud_filtered->points.size (); // 点云总数
  // While 30% of the original cloud is still there
  while (cloud_filtered->points.size () > 0.3 * nr_points)
  {
    // 为了处理点云包含的多个模型,在一个循环中执行该过程并在每次模型被提取后,保存剩余的点进行迭代
    seg.setInputCloud (cloud_filtered);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
      std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
      break;
    }

    // Extract the inliers
    extract.setInputCloud (cloud_filtered);
    extract.setIndices (inliers);  // 
    extract.setNegative (false);
    extract.filter (*cloud_p);
    std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;

    std::stringstream ss;
    ss << "../table_scene_lms400_plane_" << i << ".pcd";
    writer.write<pcl::PointXYZ> (ss.str (), *cloud_p, false);

    // Create the filtering object
    extract.setNegative (true);
    extract.filter (*cloud_f);
    cloud_filtered.swap (cloud_f);
    i++;
  }

  return (0);
}

看一下结果:

table_scene_lms400
在这里插入图片描述

table_scene_lms400_downsampled

在这里插入图片描述

table_scene_lms400_plane_0

在这里插入图片描述

table_scene_lms400_plane_1

在这里插入图片描述

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(extract_indices)

find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (extract_indices extract_indices.cpp)
target_link_libraries (extract_indices ${PCL_LIBRARIES})

用ConditionalRemoval或RadiusOutlinerRemoval移除离群点

本文档演示了如何使用过滤器模块中的几种不同方法从PointCloud中删除离群值。

首先,了解如何使用ConditionalRemoval过滤器,该过滤器删除给定输入云中不满足一个或多个给定条件的所有索引。

然后,学习如何创建一个RadiusOutlierRemoval过滤器,该过滤器删除其输入云中的所有索引,这些索引在一定范围内至少没有一些邻居。

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>

int main(int argc, char **argv)
{
  if (argc != 2) //确保输入的参数
  {
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

  //填充点云
  cloud->width = 5;
  cloud->height = 1;
  cloud->points.resize(cloud->width * cloud->height);

  for (size_t i = 0; i < cloud->points.size(); ++i)
  {
    cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
    cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
    cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
  }

  if (strcmp(argv[1], "-r") == 0)
  {                                                  // RadiusOutlierRemoval
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem; //创建滤波器

    outrem.setInputCloud(cloud);       //设置输入点云
    outrem.setRadiusSearch(0.8);       //设置半径为0.8的范围内找临近点
    outrem.setMinNeighborsInRadius(2); //设置查询点的邻域点集数小于2的删除
    // apply filter
    outrem.filter(*cloud_filtered); //执行条件滤波   在半径为0.8 在此半径内必须要有两个邻居点,此点才会保存
  }
  else if (strcmp(argv[1], "-c") == 0)
  { //RadiusOutlierRemoval
    //创建条件限定的下的滤波器
    pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>()); //创建条件定义对象
    //添加在Z字段上大于0的比较算子
    //GT greater than
    //EQ equal
    //LT less than
    //GE greater than or equal
    //LE less than

    //为条件定义对象添加比较算子
    range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::GT, 0.0))); //添加在Z字段上大于0的比较算子

    range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::LT, 0.8))); //添加在Z字段上小于0.8的比较算子
    // 创建滤波器并用条件定义对象初始化
    pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
    condrem.setCondition(range_cond);
    condrem.setInputCloud(cloud);   //输入点云
    condrem.setKeepOrganized(true); //设置保持点云的结构
                                    // 设置是否保留滤波后删除的点,以保持点云的有序性,通过setuserFilterValue设置的值填充点云;或从点云中删除滤波后的点,从而改变其组织结构
                                    // 如果设置为true且不设置setUserFilterValue的值,则用nan填充点云
                                    //  https://blog.csdn.net/qq_37124765/article/details/82262863

    // 执行滤波
    condrem.filter(*cloud_filtered); //大于0.0小于0.8这两个条件用于建立滤波器
  }
  else
  {
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  std::cerr << "Cloud before filtering: " << std::endl;
  for (size_t i = 0; i < cloud->points.size(); ++i)
    std::cerr << "    " << cloud->points[i].x << " "
              << cloud->points[i].y << " "
              << cloud->points[i].z << std::endl;
  // display pointcloud after filtering
  std::cerr << "Cloud after filtering: " << std::endl;
  for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
    std::cerr << "    " << cloud_filtered->points[i].x << " "
              << cloud_filtered->points[i].y << " "
              << cloud_filtered->points[i].z << std::endl;
  return (0);
}

下面的图片有助于可视化RadiusOutlierRemoval过滤器对象的作用。用户指定邻居的数量,每个索引必须在指定的半径内保持在PointCloud中。例如,如果指定了1个邻居,则只有黄色的点会从PointCloud中移除。如果指定了2个邻居,那么黄色点和绿色点都将从PointCloud中移除。

在这里插入图片描述

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(remove_outliers)

find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (remove_outliers remove_outliers.cpp)
target_link_libraries (remove_outliers ${PCL_LIBRARIES})

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

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

相关文章

CSS设置单行文字水平垂直居中的方法

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>单行文字水平垂直居中</title><style>div {/* 给div设置宽高 */width: 400px;height: 200px;margin: 100px auto;background-color: red;/…

【深度学习每日小知识】Bias 偏差

计算机视觉是人工智能的一个分支&#xff0c;它使机器能够解释和分析视觉信息。然而&#xff0c;与任何人造技术一样&#xff0c;计算机视觉系统很容易受到训练数据产生的偏差的影响。计算机视觉中的偏见可能会导致不公平和歧视性的结果&#xff0c;从而使社会不平等长期存在。…

[GYCTF2020]Ezsqli1

打开环境&#xff0c;下面有个提交表单 提交1&#xff0c;2有正确的查询结果&#xff0c;3以后都显示Error Occured When Fetch Result. 题目是sql&#xff0c;应该考察的是sql注入 简单fuzz一下 发现information_schema被过滤了&#xff0c;猜测是盲注了。 测试发现只要有东…

【MySQL】学习如何通过DML更新数据库的数据

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-QIqURn9fNFMjLD9l {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

火车票车票查询-Python

一、相关代码 # Time: 2024/1/22 20:24 # Author: 马龙强 # File: 实现12306查票购票.py # software: PyCharm """网址&#xff1a;https://www.12306.cn/index/ 数据&#xff1a;车次信息 查票链接&#xff1a;https://kyfw.12306.cn/otn/leftTicket/queryE?…

四、vtk相机类vtkCamera的使用

在三维渲染场景中,相机好比观众的眼睛,人站立的位置影响事物的大小,视角的不同影响看到事物的范围,目光的朝向影响看到事物的正反。 vtkCamera负责把三维场景投影到二维平面,如屏幕、图像等。 下图为相机投影示意图: 相机位置:即相机所在的位置,用方法vtkCamera::Se…

【Linux】进程间通信概念 | 匿名管道

文章目录 一、什么是进程间通信进程间通信的概念进程间通信的目的进程间通信的分类进程间通信的本质 二、什么是管道三、匿名管道匿名管道的原理✨站在内核角度理解管道✨站在文件描述符角度理解管道 pipe系统调用fork后在父子进程间使用管道通信代码实现 匿名管道的读写规则管…

【论文笔记】《Learning Deconvolution Network for Semantic Segmentation》

重要说明&#xff1a;严格来说&#xff0c;论文所指的反卷积并不是真正的 deconvolution network 。 关于 deconvolution network 的详细介绍&#xff0c;请参考另一篇博客&#xff1a;什么是Deconvolutional Network&#xff1f; 一、参考资料 Learning Deconvolution Netwo…

【C语言刷题系列】交换两个变量的三种方式

文章目录 1.使用临时变量&#xff08;推荐&#xff09; 2.相加和相减的方式&#xff08;值较大时可能丢失数据&#xff09; 3.按位异或运算 本文所属专栏C语言刷题_倔强的石头106的博客-CSDN博客 两个变量值的交换是编程中最常见的问题之一&#xff0c;以下将介绍三种变量的…

数据结构(1)--> 顺序表

定义&#xff1a; 顺序表存储定义&#xff1a; 把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构&#xff0c;顺序表功能的实现借助于数组&#xff0c;通过对数组进行封装&#xff0c;从而实现增删查改的功能&#xff0c;严格意义上来说&#xff08;数组无法实现…

python在线聊天室(带聊天保存)

python Socket在线聊天室(带聊天保存) 需求功能 1.聊天信息保存功能(服务端会把信息保存到一个txt里面) 2.使用pyqt5框架作为一个可视化界面 3.具备一个服务端和多个客户端的功能 4.具备离线加入黑名单(离线踢出) 5.具备在线加入黑名单(在线加入黑名单被踢出) 6.具备群聊功能…

JasperReports渲染报表文件时候,读取图片报错:Byte data not found at:xxx.png.\r\n\tat

目录【知识星球】 1.1、错误描述 1.2、解决方案 1.1、错误描述 最近在工作中&#xff0c;使用JasperReports报表比较多一些&#xff0c;有次线上环境里面运行报错&#xff0c;查看报错日志&#xff0c;如下所示&#xff1a; net.sf.jasperreports.engine.JRException: Byte…

批量数据之DataX数据同步

文章目录 1 DataX1.1 引言1.2 DataX 简介1.3 核心1.3.1 DataX3.0 框架设计1.3.2 DataX3.0 核心架构 1.4 使用 DataX 实现数据同步1.4.1 准备安装1.4.2 Linux 上安装 DataX 软件1.4.3 DataX 基本使用1.4.4 MySQL 数据库1.4.4.1 安装1.4.4.2 准备同步1.4.4.3 创建存储过程&#x…

第15次修改了可删除可持久保存的前端html备忘录:换了一个容器时钟,匹配背景主题:现代深色

第15次修改了可删除可持久保存的前端html备忘录&#xff1a;换了一个容器时钟&#xff0c;匹配背景主题&#xff1a;现代深色 备忘录代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv&qu…

适用于 Windows 的 10 个最佳数据恢复工具学习

在数字时代&#xff0c;数据就是一切。从珍贵的家庭照片和重要的工作文档到最喜欢的音乐和电影&#xff0c;我们的生活越来越多地存储在各种设备上。系统崩溃、意外删除或恶意病毒都可能使您的宝贵数据瞬间消失。这就是数据恢复工具的用武之地。 10 个最佳数据恢复工具 这些软…

【无标题】Gateway API 实践之(五)FSM Gateway 的会话保持功能

网关的会话保持功能是一种网络技术&#xff0c;旨在确保用户的连续请求在一段时间内被定向到同一台后端服务器。这种功能在需要保持用户状态或进行连续交互的场景中特别重要&#xff0c;例如在维护在线购物车、保持用户登录状态或处理多步骤事务时。 会话保持通过提供一致的用…

代码随想录算法刷题训练营day17

代码随想录算法刷题训练营day17&#xff1a;LeetCode(110)平衡二叉树 LeetCode(110)平衡二叉树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(…

关于AOP的@Around特殊处理RequestBody的使用小结

目录 1. 概述 1.1 背景 1.2 源码 2. 测试 2.1 Controller 2.2 SpecialName配置 2.3 RequestConverter 2.4 测试 最近项目上遇到一个这样的需求&#xff1a;用户请求的时候传过来A&#xff0c;在api处理过程中要把A当成B去处理&#xff0c;但是返回的标识中又必须是A作为…

vue2 事件总线

原图下载&#xff1a;https://download.csdn.net/download/weixin_47401101/88788636

【开源】基于JAVA语言的二手车交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块2.3 车辆预约管理模块2.4 车辆预定管理模块2.5 车辆留言板管理模块2.6 车辆资讯管理模块 三、系统设计3.1 E-R图设计3.2 可行性分析3.2.1 技术可行性分析3.2.2 操作可行性3.2.3 经济…