PCL学习记录-1 Filter-1 PassThrough filter(直通滤波器)功能及用法解析

PCL系列博客主要用来记录学习PointCloudLibrary点云库的过程,以及备忘。

学习资料主要来源为: PCL点云库(Tutorial)+Github博客+ 《点云库PCL学习教程

!Update: 需要注意的是,单个直通滤波器仅仅可以过滤一个坐标轴方向上的点云;

                 例: 当设置pt.setFilterYlimit(-0.5,0.5) 时, 过滤完成后,仅保留y方向上,-0.5~+0.5区域点云,其余舍弃;

                         若在程序中,依次设置了setFilterXlimit ,setFilterYlimit,和setFilterZlimit 的参数, 仅有最后一个Z方向上的滤波生效,其余两个被舍弃;(原因为:直通滤波器,仅能过滤一个方向上的点云                      

引:为什么要进行滤波,以及PCL点云库中,包含的几种常用的滤波方法简介

  在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,以及电磁波衍射特性、被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免地出现一些噪声点。实际应用中除了这些测量随机误差产生的噪声点之外,由于受到外界干扰如视线遮挡、障碍物等因素的影响,点云数据中往往存在着一些离主体点云较远的离散点,即离群点。不同的获取设备点云噪声结构也有不同。

  通过滤波完成的功能还包括孔洞修复、最小信息损失的海量点云数据压缩处理等在点云处理流程中滤波处理作为预处理的第一步,往往对后续处理流程影响很大,只有在滤波预处理中将噪声点、离群点、孔洞、数据压缩等 按照后续需求处理,才能够更好地进行配准、特征提取、曲面重建、可视化等后续流程。

  PCL 中点云滤波模块提供了很多灵活实用的滤波处理算法,例如双边滤波、高斯滤波、条件滤波、直通滤波、基于随机采样一致性滤波RANSAC等。滤波模块是作为 PCL的一个重要处理模块,其在应用中可以非常方便与其他点云处理流程协同使用。

  • 滤波相关文档:

      https://pcl-tutorials.readthedocs.io/en/latest/#filtering

  • 应用场景
  1. 点云数据密度不规则需要平滑处理
  2. 去除因为遮挡等问题造成离群点
  3. 数据量较大,需要进行下采样( Downsample)
  4. 去除噪声数据。
  • 示例

     下图显示了一个噪声消除的示例。 由于测量误差,某些数据集会出现大量阴影点。 这使局部点云3D特征的估算变得复杂。我们通过对每个点的邻域进行统计分析,并修剪掉不符合特定条件的那些异常值,进而可以过滤掉某些异常值。

      PCL中的实现这些稀疏离群值的消除,需要计算数据集中的点与邻居距离的分布。 即对于每个点,都会计算从它到所有相邻点的平均距离。 通过假设结果分布是具有均值和标准差的高斯分布,可以将那些平均距离在【由全局距离均值和标准差定义的区间】之外的所有点视为离群值,并将之从数据集中进行修剪。

_images/statistical_removal_2.jpg


一. PassThroughFilter(直通滤波)

PassThroughFilter直通滤波原理:直通滤波主要功能是将设置范围之外(距离原点XYZ距离范围)的全部点给过滤掉,或者仅保留该区域的点。

直通滤波的主要使用过程(以官方Tutorial为例:https://pcl.readthedocs.io/projects/tutorials/en/latest/passthrough.html#passthrough):

  1. 创建待处理点云对象,以及存储点云处理完成后的点云对象。
  2. 设置点云的容量:宽+高+长×宽;
  3. 设置点云内所有点的xyz坐标;
  4. 创建PassThroughFilter对象,并设置其滤波参数。
  5. 将待处理点云对象作为filter的输入进行滤波;
  6. 得到结果:在filter对象设置的x,y,z的范围之内的点将被保留,范围之外的点将被舍弃,实现直通滤波的功能

二.直通滤波的代码:

1. PassThroughFilter.cpp

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char ** argv){
    //step1. 创建处理前及处理之后的点云对象
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);

    //step2, 设置处理前的点云对象(容量大小,点位置等)(声明对象->确定大小->为每个点赋值)
    cloud->width=5;
    cloud->height=1;
    cloud->points.resize(cloud->width *  cloud->height);

    for (auto& point: *cloud ){
    point.x=1024 * rand()/(RAND_MAX +1.0f);
    point.y=1024 * rand()/(RAND_MAX +1.0f);  
    point.z=1024 * rand()/(RAND_MAX +1.0f);  
    }

    //step3. 至此,实例点云已经生成完毕,输出处理前的点云信息
    std::cerr <<"The points data are shown below:" <<std::endl;
    for(const auto &point: *cloud){
        std::cerr<< "  "<<point.x<< "  "
                        <<point.y<< "  "
                        <<point.z<< std::endl;
    }
    //step4: 创建直通滤波对象
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0.0,1.0);
    pass.filter(*filtered_cloud);//存储处理之后的点云
    
    
    /************************************************************************************
   创建直通滤波器的对象,设立参数,滤波字段名被设置为Z轴方向,可接受的范围为(0.0,1.0)
   即将点云中所有点的Z轴坐标不在该范围内的点过滤掉或保留,这里是过滤掉,由函数setFilterLimitsNegative设定
   ***********************************************************************************/


    //step5. 显示处理之后的点云详细信息
    std::cerr<<"The pointcloud has been processed successfully"<< std::endl;
        for(const auto &point: *filtered_cloud){
        std::cerr<< "  "<<point.x<< "  "
                        <<point.y<< "  "
                        <<point.z<< std::endl;
    } 
    //Display
    pcl::visualization::CloudViewer viewer("Cloud Viewer");
    viewer.showCloud(filtered_cloud);
    while (!viewer.wasStopped()) {
    }

    return (0);

}

2. CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(passthroughfilter)

find_package(PCL 1.2 REQUIRED)

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

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

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

3.运行结果:可以看到,随机生成了5个点,其中两个点的Z坐标处于范围内(得到保留),另外两个点在范围外(被舍弃)

anson@anson-Inspiron:~/PCL_learning/PCL_Official_Online_Learning/01_Filters/01_PassThroughFilter/build$ ./passthroughfilter 
The points data are shown below:
  0.352222  -0.151883  -0.106395
  -0.397406  -0.473106  0.292602
  -0.731898  0.667105  0.441304
  -0.734766  0.854581  -0.0361733
  -0.4607  -0.277468  -0.916762
The pointcloud has been processed successfully
  -0.397406  -0.473106  0.292602
  -0.731898  0.667105  0.441304
^C
anson@anson-Inspiron:~/PCL_learning/PCL_Official_Online_Learning/01_Filters/01_PassThroughFilter/build$ ./passthroughfilter 
The points data are shown below:
  0.352222  -0.151883  -0.106395
  -0.397406  -0.473106  0.292602
  -0.731898  0.667105  0.441304
  -0.734766  0.854581  -0.0361733
  -0.4607  -0.277468  -0.916762
The pointcloud has been processed successfully
  -0.397406  -0.473106  0.292602
  -0.731898  0.667105  0.441304
^C

 

 

 

 

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页