PCL教程-点云滤波之直通滤波器

本文详细介绍了PCL库中的直通滤波器(PassThrough)的工作原理和使用方法,用于去除点云中特定维度超出给定范围的点。通过设置滤波字段和值域,可以有效地筛选点云数据。示例代码演示了如何在Z轴方向上进行滤波,保留Z值在0~1之间的点,从而实现点云的初步过滤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

算法原理

直通滤波的作用是过滤掉在指定维度方向上取值不在给定值域内的点。

实现原理如下:

首先,指定一个维度以及该维度下的值域,其次,遍历点云中的每个点,判断该点在指定维度上的取值是否在值域内,删除取值不在值域内的点,最后,遍历结束,留下的点即构成滤波后的点云。直通滤波器简单高效,适用于消除背景等操作。

PCL中的pcl:PassThrough类实现对用户给定点云某个字段的限定下,对点云进行简单的基本过滤,例如限制过滤掉点云中所有Z字段不在某个范围内的点,该类的使用比较灵活但完全取决于用户的限定字段和对应条件。


关键成员函数

设置限定字段的名称字符串field_ name,例如"z",等:

void setFilterFieldName(const std::string &field_ name)

设置滤波限制条件

包括最小值limit_ min和最大值limit_max。该函数与set-FilterFieldName()一起使用,点云中所有点的setFilterFieldName)()设置的字段的值未在用户所设定区间范围外的点将被删除。参数limit_min为允许的区间范围的最小值,默认为DBL_MIN, limit_max为允许的区间范围的最大值,默认为DBL_MAX.

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

设置返回滤波限制条件外的点还是内部点

limit_negative默认值为false,输出点云为在设定字段的设定范围内的点集,如果设置为true则刚好相反。警告:该方法将来将会被移除,用setNegative()函数代替。

void getFilterLimitsNegative (bool &limit_negative)

程序代码

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
 main (int argc, char** argv)
{ 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);		//设置滤波范围为0~1,在范围之外的点会被剪除
  //pass.setFilterLimitsNegative (true);//是否反向过滤,默认为false
  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);
}

 实验结果

Cloud before filtering:
    0.0873413 0.418091 -0.331146
    -0.367493 -0.240753 0.329285
    0.258301 -0.415497 -0.326172
    0.478882 -0.485962 -0.450592
    0.0456543 0.17511 0.156433
Cloud after filtering:
    -0.367493 -0.240753 0.329285
    0.0456543 0.17511 0.156433

本此案例中设置的是对 z 轴进行滤波,滤波范围为0~1.0,所以z坐标为负的点已全部过滤掉。 

在Python中,我们可以使用PCL (Point Cloud Library) 或相关的点云处理库来实现点云数据格式转换和滤波。以下是基本步骤: (2)完成点云数据格式转换(Python): ```python from pyntcloud import PyntCloud # 假设我们有原始点云数据(如XYZ格式) raw_cloud = load_point_cloud("input.pcd") # 这里假设load_point_cloud函数从文件加载数据 # 转换为另一种格式,比如转换为PCD格式(采用PCL) pcd = raw_cloud.to_pcl() # 如果输入是PyntCloud对象,to_pcl()会将其转换成PCL PointCloud2对象 # 写入新文件 pcd.save("output.pcd") ``` 注意:`load_point_cloud()` 和 `save()` 函数取决于实际使用的库和数据源。 (3)点云滤波方法实现(Python,以直通滤波器为例): ```python import pcl def apply_pass_through_filter(point_cloud): # 创建直通滤波器 passthrough = pcl.PCLPointCloud2() passthrough.setInputCloud(point_cloud) # 定义过滤范围(例如,保留所有Z值在0到1之间的点) filter_axis = 'z' min_value = 0.0 max_value = 1.0 passthrough.filter_passthrough_range(min_max=([min_value], [max_value]), axis=filter_axis) return passthrough # 加载点云并应用滤波器 filtered_cloud = apply_pass_through_filter(pcd) # 可能需要进一步处理,如保存结果 filtered_cloud.save("filtered_output.pcd") ``` 这里我们使用了PCL直通滤波器(passthrough range filter)。对于其他滤波器,如体素滤波、统计滤波等,PCL库中都有相应的类和方法。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SOC罗三炮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值