【三维点云数据处理】PCL直通滤波器

一、 算法原理

        直通滤波器:class pcl: : PassThrough<< PointT >
对指定维度(X,Y,Z,BGR等)进行某一个范围滤波,可以删除这个范围内部点,也可以删除这个范围外部的点。
类 PassThrough 实现对用户给定点云某个字段的限定下 , 对点云进行简单的基本过滤 , 例如限制过滤掉点云中所有 X 字段不在某个范围内的点 , 该类的使用比较灵活但完全取欧于用户的限定字段和对应条件。

关键函数

关键成员函数 :

void setFilterFieldName (const std: :string &.field_name)

设置限定字段的名称字符串 field_name, 例如“z“等。

void setFilterLimits (const double &limit_min, const double & limit_max)

设置滤波限制条件 , 包括最小值 limit_min 和最大值 limit_max。该函数与 setFilterFieldName( 一起使用 , 点云中所有点的 setFilterFieldName( ) 设置的字段的值未在用户所设定区间范围外的点将被删除。参数 limit_min 为允许的区间范围的最小值 , 默认为 DBL _ MIN, limit_max 为允许的区间范围的最大值 , 默认为DB L_MAX。

void getFilterLimitsNegative (bool &limit_negative) 

设置返回滤波限制条件外的点还是内部点,limit_negative默认值是false,输出点云为在设定字段的设定范围内的点,设为true则正好相反。

二、代码实例

1. 代码示例1

#include <QCoreApplication>
#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
 main ()
{ srand(time(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 = rand () / (RAND_MAX + 1.0f)-0.5;
    cloud->points[i].y = rand () / (RAND_MAX + 1.0f)-0.5;
    cloud->points[i].z = rand () / (RAND_MAX + 1.0f)-0.5;
  }
  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;
  // 创建滤波器对象
  pcl::PassThrough<pcl::PointXYZ> pass;     //设置滤波器对象
  pass.setInputCloud (cloud);               //设置输入点云
  pass.setFilterFieldName ("z");            //设置过滤时所需要的点云类型的Z字段
  pass.setFilterLimits (0.0, 1.0);          //设置在过滤字段上的范围
  //pass.setFilterLimitsNegative (true);    //设置保留范围内的还是过滤掉范围内的
  pass.filter (*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);
}

2.代码示例2

#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <pcl/ModelCoefficients.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>
using namespace std;
typedef pcl::PointXYZ PointType;


int main(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
         //创建存储模型系数的对象
        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.setDistanceThreshold(0.1);  //设置距离阀值,可调节分割平面的点数(平面精度),需要根据实际采样点集设置
        seg.setInputCloud(cloud);
        seg.segment(*inliers, *coefficients); //coefficients存储平面参数,inlier为平面点索引

        /*提取平面点*/
        pcl::ExtractIndices<pcl::PointXYZ> extract;
        extract.setInputCloud(cloud);
        extract.setIndices(inliers);
        extract.setNegative(false); //设置提取平面点。(若为true,则是提取的非平面点,inliers之外的点)
        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p (new pcl::PointCloud<pcl::PointXYZ>);
        extract.filter(*cloud_p);   //最终cloud_p为平面点云


        //visualization
        pcl::visualization::PCLVisualizer viewer;

        pcl::visualization::PointCloudColorHandlerCustom<PointType> tc_handler(cloud_p, 0, 0, 0); //转换到原点的点云相关
        viewer.addPointCloud(cloud_p, tc_handler, "transformCloud");

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

        //保存结果
        pcl::io::savePCDFile("result.pcd",*cloud_p);
        return 0;
}

三、结果展示

示例1结果展示

在这里插入图片描述

示例2结果展示

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云兔子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值