算法原理
直通滤波的作用是过滤掉在指定维度方向上取值不在给定值域内的点。
实现原理如下:
首先,指定一个维度以及该维度下的值域,其次,遍历点云中的每个点,判断该点在指定维度上的取值是否在值域内,删除取值不在值域内的点,最后,遍历结束,留下的点即构成滤波后的点云。直通滤波器简单高效,适用于消除背景等操作。
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坐标为负的点已全部过滤掉。