各种滤波方法类对点云滤波的整体流程:

        使用对应滤波器方法类设置滤波器对象------将待滤波的点云添加到滤波器对象------根据相应滤波的的特性设置滤波器的各个参数------设置滤波条件------采用滤波方法滤波,将滤波后的点云输出

例子:直通滤波器对点云滤波 

1,创建pass滤波器对象; pcl::PassThrough<pcl::PointXYZ> pass(true/false);

                首先创建passthrough滤波器对象,如果后续过程依然要使用被滤除点,我们必须保存被滤除点的索引以供后续使用,那么创建滤波器对象时,必须设置为true,默认构造函数创建滤波器对象时默认参数是false,不保存被滤除点的索引。

2,添加滤波对象两种方式,

一是添加指向点云的指针;

pcl::PointCloud<pcl::PointXYZ>::Ptr cloudnew(pcl::PointCloud<pcl::PointXYZ>)

pass.setInputCloud(cloud);

二是添加指向点云索引的指针;

pcl::IndicesConstPtr my_indicies;

pass.setIndicies(my_indicies);

三是设置滤波器的各种参数;

pass.setFilterFieldName(const std::string):设置在那个属性字段上做滤波处理;
pass.setFilterLimits(double a,double b):设置滤波的区间限制;
pass.setFilterLimitsNegative(bool):设置滤除区间内的点还是区间外的点;
pass.filter(*pointcloud_ptr):滤波后的点云的输出;

程序如下:

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include<pcl/visualization/pcl_visualizer.h>
#include<pcl/common/common_headers.h>


int main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudIn(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut1(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut2(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut3(new pcl::PointCloud<pcl::PointXYZ>);

//创建一个圆柱类型点云,半径radius=1,z=[-1,1]
    pcl::PointXYZ point;
    for (float z = -1; z <= 1; z += 0.05)
    {
        for (double angle = 0; angle <= 360.0; angle += 5.0)
        {
            point.x = cos(pcl::deg2rad(angle));
            point.y = sin(pcl::deg2rad(angle));
            point.z = z;
            cloudIn->points.push_back(point);
    
        }
    }

    // 创建直通滤波器对象
    pcl::PassThrough<pcl::PointXYZ> pass(true); //设置为true,要保留被滤除点的索引;
    pass.setInputCloud(cloudIn);    
    //首先沿着x字段滤波
    pass.setFilterFieldName("x");   
    pass.setFilterLimits(0.0, 1.0);     //滤波区间x[0,1]
    
    pass.setFilterLimitsNegative (false);   //false:要滤除[0,1]外部的点
    pass.filter(*cloudOut1);
   /* cout << pass.getFilterFieldName() << endl;
    float a, b;
    pass.getFilterLimits(a, b);
    cout << "a=" << a << "," << "b=" << b << endl;
    cout << pass.getNegative() << endl;*/
    pcl::IndicesConstPtr removedIndicies1;
    removedIndicies1 = pass.getRemovedIndices();
    pass.setIndices(removedIndicies1);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0.0, 1.0);
    pass.setFilterLimitsNegative(true); //true:要滤除在z[0,1]区间内的点
    pass.filter(*cloudOut2);

    pcl::IndicesConstPtr removedIndicies2;
    removedIndicies2 = pass.getRemovedIndices();
    pass.setIndices(removedIndicies2);
    pass.setFilterFieldName("y");
    pass.setFilterLimits(0.0, 1.0);
    pass.setFilterLimitsNegative(true); //true:要滤除在y[0,1]区间内的点
    pass.filter(*cloudOut3);

    //创建可视窗口
    pcl::visualization::PCLVisualizer viewer("3D viewer");

    int v1(0);
    viewer.createViewPort(0, 0, 0.5, 0.5, v1);
    viewer.setBackgroundColor(0, 0, 0, v1);
    viewer.addPointCloud(cloudIn, "cloud1", v1);
    viewer.addCoordinateSystem(0.5, "coordinatysystem1", v1);
    viewer.addText("v1", 10, 10, "text1", v1);

    int v2(0);
    viewer.createViewPort(0.5, 0, 1, 0.5, v2);
    viewer.setBackgroundColor(0, 0, 0, v2);
    viewer.addPointCloud(cloudOut1, "cloud2", v2);
    viewer.addCoordinateSystem( 0.5,"coordinatysystem2", v2);
    viewer.addText("v2", 10, 10, "text2", v2);


    int v3(0);
    viewer.createViewPort(0, 0.5, 0.5, 1, v3);
    viewer.setBackgroundColor(0, 0, 0, v3);
    viewer.addPointCloud(cloudOut2, "cloud3", v3);
    viewer.addCoordinateSystem(0.5, "coordinatysystem3", v3);
    viewer.addText("v3", 10, 10, "text3", v3);


    int v4(0);
    viewer.createViewPort(0.5, 0.5, 1, 1, v4);
    viewer.setBackgroundColor(0, 0, 0, v4);
    viewer.addPointCloud(cloudOut3, "cloud4", v4);
    viewer.addCoordinateSystem(0.5, "coordinatysystem4", v4);
    viewer.addText("v4", 10, 10, "text4", v4);

    while (!viewer.wasStopped())
    {
        viewer.spinOnce(100);
    }

    return (0);
}

结果如下图所示:可知:

1,pcl库中可视窗口的坐标原点在左下角;

2,v2视口为v1视口原始点云沿着x字段滤波得到的[0,1]区间内的点云;

3,v3视口为v1原始点云经过第一次滤波被滤除点云沿着z方向滤波,得到区间[-1,0]的点云;

4,v4视口为第二次滤波被滤除的点云在y方向的滤波,可知,对于一个滤波器对象pass连续使用发法getRemoveIndices()返回的仅仅是上一次滤波被滤除点云的索引值,上上一次滤波被滤除的点云的索引就被覆盖点不存在了。

点云滤波补全 python terrasolid点云滤波教程_c++

点云滤波补全 python terrasolid点云滤波教程_点云_02

来自源码: 

passthrough.h头文件

namespace  pcl
{
    ......
    1,    默认构造函数,如果要保存被滤除点云的索引,应设置为true,默认是不保存false.
    PassThrough (bool extract_removed_indices = false) :
        FilterIndices<PointT> (extract_removed_indices),
        filter_field_name_ (""),
        filter_limit_min_ (FLT_MIN),
        filter_limit_max_ (FLT_MAX)
      {
        filter_name_ = "PassThrough";
      }
      
    2,设置滤波字段,获取滤波字段。
     
     inline void
      setFilterFieldName (const std::string &field_name)
      {
        filter_field_name_ = field_name;
      }

 
      inline std::string const
      getFilterFieldName () const
      {
        return (filter_field_name_);
      }

    3,设置滤波区间范围,获取滤波区间范围
    inline void
      setFilterLimits (const float &limit_min, const float &limit_max)
      {
        filter_limit_min_ = limit_min;
        filter_limit_max_ = limit_max;
      }

      inline void
      getFilterLimits (float &limit_min, float &limit_max) const
      {
        limit_min = filter_limit_min_;
        limit_max = filter_limit_max_;
      }

    4,设置滤除区间内的点还是区间外的点,true:滤除区间内的点,false:滤除区间外的点。获取该设置参数,该函数可以使用getNegative()函数代替使用。
      PCL_DEPRECATED(1, 13, "use inherited FilterIndices::setNegative() instead")
      inline void
      setFilterLimitsNegative (const bool limit_negative)
      {
        negative_ = limit_negative;
      }

      PCL_DEPRECATED(1, 13, "use inherited FilterIndices::getNegative() instead")
      inline void
      getFilterLimitsNegative (bool &limit_negative) const
      {
        limit_negative = negative_;
      }
    ......
}

filter.h头文件
namespace pcl
{
    class Filter
   {

      inline void
      getRemovedIndices (PointIndices &pi)
      {
        pi.indices = *removed_indices_;
      }

  }
}


pcl_base.hpp文件

template <typename PointT> void
pcl::PCLBase<PointT>::setIndices (const IndicesConstPtr &indices)
{
  indices_.reset (new Indices (*indices));
  fake_indices_ = false;
  use_indices_  = true;
}

///
template <typename PointT> void
pcl::PCLBase<PointT>::setIndices (const PointIndicesConstPtr &indices)
{
  indices_.reset (new Indices (indices->indices));
  fake_indices_ = false;
  use_indices_  = true;
}