PCL学习笔记四- filters滤波/降采样

09 filters滤波/降采样 (yuque.com)

理论

PCL中总结了几种需要进行点云滤波处理情况,这几种情况分别如下:

 (1)  点云数据密度不规则需要平滑

 (2) 因为遮挡等问题造成离群点需要去除

 (3) 大量数据需要下采样

 (4) 噪声数据需要去除

对应的方案如下:

 (1)按照给定的规则限制过滤去除点

 (2) 通过常用滤波算法修改点的部分属性

 (3)对数据进行下采样

PCL点云格式分为有序点云和无序点云

  • 针对有序点云提供了双边滤波、高斯滤波、中值滤波等
  • 针对无序点云提供了体素栅格、随机采样等

是根据传感器的采集数据上来说

  • 一般深度相机采集到的点云的数据是有序点云
  • 而我们激光雷达采集的点云的数据是无序的点云

类&函数介绍

Classes

pcl::ApproximateVoxelGrid< PointT >   类ApproximateVoxelGrid根据给定的点云形成三维体素栅格,并利用所有体素的中心点近似体素

中包含的点集,这样完成下采样得到滤波结果,该类比较合适对海量点云数据在处理前进行压缩,提高算法效率

class  

pcl::BilateralFilter< PointT >  类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用

强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,

class  

pcl::BoxClipper3D< PointT >实现用一个原点为中心,XYZ各个方向尺寸为2  经过用户指定的仿射变换的立方体进行空间裁剪,通过设置一个仿射变换矩阵先对立方体进行变换处理,之后输出仿射变换后落在该立方体内的点集

class  

pcl::Clipper3D< PointT >是3D空间裁剪对象的基类

class  

pcl::ConditionalRemoval< PointT >实现过滤满足一定的条件的点云数据,非常灵活,可以设置滤波条件

class  

pcl::filters::Convolution< PointIn, PointOut >   实现卷积滤波处理

class  

pcl::filters::ConvolvingKernel< PointInT, PointOutT >  是所有卷积核的基类

class  

pcl::filters::GaussianKernel< PointInT, PointOutT >  是基于高斯核的卷积滤波实现  高斯滤波相当于一个具有平滑性能的低通滤波器

class  

pcl::filters::GaussianKernelRGB< PointInT, PointOutT >   是附加RGB通道基于高斯核的卷积滤波实现,不仅考虑空间XYZ而且考虑RGB

class  

pcl::CropBox< PointT >    过滤掉在用户给定立方体内的点云数据

class  

pcl::CropHull< PointT >   过滤在给定三维封闭曲面或二维封闭多边形内部或外部的点云数据

class  

pcl::ExtractIndices< PointT >  从一个点云中提取索引

class  

pcl::Filter< PointT >  是滤波模块最重要的类  其他所有的滤波模块的类都从它继承。

             。。。。。。。。。。(还有很多)

官方Tutorials

Filtering a PointCloud using a PassThrough filter 在PCL 中使用直通滤波器对点云进行滤波处理

Downsampling a PointCloud using a VoxelGrid filter 使用VoxelGrid滤波器对点云进行下采样

Removing outliers using a StatisticalOutlierRemoval filter 使用statisticalOutlierRemoval滤波器移除离群点

Projecting points using a parametric model 使用参数化模型投影点云

Extracting indices from a PointCloud 从一个点云中提取索引

Removing outliers using a Conditional or RadiusOutlier removal 用ConditionalRemoval  或RadiusOutlinerRemoval移除离群点

1 pcl::PassThrough直通滤波器进行滤波处理

/*
 * @Description: 在PCL 中使用直通滤波器对点云进行滤波处理  https://www.cnblogs.com/li-yao7758258/p/6445831.html
 * @Author: HCQ
 * @Company(School): UCAS
 * @Email: 1756260160@qq.com
 * @Date: 2020-10-20 10:36:02
 * @LastEditTime: 2020-10-20 10:45:57
 * @FilePath: /pcl-learning/09filters滤波/1直通滤波器进行滤波处理/passthrough.cpp
 */
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>

int
 main (int argc, char** argv)
{
  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);
  }

  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;
  /************************************************************************************
   创建直通滤波器的对象,设立参数,滤波字段名被设置为Z轴方向,可接受的范围为(0.0,1.0)
   即将点云中所有点的Z轴坐标不在该范围内的点过滤掉或保留,这里是过滤掉,由函数setFilterLimitsNegative设定
   ***********************************************************************************/
  // 设置滤波器对象
  pcl::PassThrough<pcl::PointXYZ> pass;
  pass.setInputCloud (cloud);            //设置输入点云
  pass.setFilterFieldName ("z");         //设置过滤时所需要点云类型的Z字段
  pass.setFilterLimits (0.0, 1.0);        //设置在过滤字段的范围
  //pass.setFilterLimitsNegative (true);   //设置保留范围内还是过滤掉范围内 是否保存滤波的限制范围内的点云,默认为false,保存限制范围内点云,true时候是相反。
  pass.filter (*cloud_filtered);            //执行滤波,保存过滤结果在cloud_filtered

  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);
}
cmake_minimum_required ( VERSION 2.6 FATAL_ERROR)   #对于cmake版本的最低版本的要求
project(ch2)                                        #建立的工程名,例如源代码目录路径的变量名为CH_DIR
                                                    #工程存储目录变量名为CH_BINARY_DIR
#要求工程依赖的PCL最低版本为1.3,并且版本至少包含common和IO两个模块  这里的REQUIRED意味着如果对应的库找不到 则CMake配置的过程将完全失败,
#因为PCL是模块化的,也可以如下操作:
#           一个组件  find_package(PCL 1.6 REQUIRED COMPONENTS  io)
#           多个组件  find_package(PCL 1.6 REQUIRED COMPONENTS commom io)
#           所有组件  find_package(PCL 1.6 REQUIRED )                    
find_package(PCL 1.3 REQUIRED)  


#下面的语句是利用CMake的宏完成对PCL的头文件路径和链接路径变量的配置和添加,如果缺少下面几行,生成文件的过程中就会提示
#找不到相关的头文件,在配置CMake时,当找到了安装的PCL,下面相关的包含的头文件,链接库,路径变量就会自动设置
#                    PCL_FOUND:如果找到了就会被设置为1 ,否则就不设置
#                    PCL_INCLUDE_DIRS:被设置为PCL安装的头文件和依赖头文件的目录
#                    PCL_LIBRARIES:被设置成所建立和安装的PCL库头文件
#                    PCL_LIBRARIES_DIRS:被设置成PCL库和第三方依赖的头文件所在的目录
#                    PCL_VERSION:所找到的PCL的版本
#                    PCL_COMPONENTS:列出所有可用的组件
#                    PCL_DEFINITIONS:列出所需要的预处理器定义和编译器标志
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARIES_DIRS})
add_definitions(${PCL_DEFINITIONS})

#这句话告诉CMake从单个源文件write_pcd建立一个可执行文件
add_executable(write_pcd write_pcd.cpp)
#虽然包含了PCL的头文件,因此编译器知道我们现在访问所用的方法,我们也需要让链接器知道所链接的库,PCL找到库文件由
#PCL_COMMON_LIBRARIES变量指示,通过target_link_libraries这个宏来出发链接操作
target_link_libraries(write_pcd ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值