PCL滤波大全、原理+代码实例+操作步骤

PCl 滤波汇总

1、直通滤波 passThrough

原理:对指定的某一维度进行滤波,去掉用户指定字段或范围内Or外的点云数据。

头文件为:

#include<pcl/filters/passthrough.h>

滤波代码实例:

	// Create the filtering object
	pcl::PassThrough<pcl::PointXYZ> pass; // 声明直通滤波
	pass.setInputCloud(cloud); 			// 传入点云数据
	pass.setFilterFieldName("z"); 		// 设置操作的坐标轴
	pass.setFilterLimits(0.0, 3.0); 	// 设置坐标范围
	pass.setFilterLimitsNegative(true); // 保留数据函数
	pass.filter(*cloud_filtered);  		// 进行滤波输出

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

如下解释:

pass.setFilterFieldName(“z”); // 设置操作的坐标轴
pass.setFilterLimits(0.0, 3.0); // 设置坐标范围

表示只操作Z轴点云数据,对0~3范围内的点云进行保存或者舍弃

pass.setFilterLimitsNegative(true); // 保留数据函数

false表示保存范围内的点云数据,true则相反

使用步骤:

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

在这里插入图片描述

2、体素滤波器 voxelGrid

原理:[下采样]减少点云数据集中点云的数量。对点云数据创建一个三维体素栅格(微小的空间三维立方体的集合),用每个体素重心近似代替体素中的其他点。这种方法比用体素中心来逼近的方法更慢,但它对于采样点对应曲面的表示更为准确。

头文件为:

#include <pcl/filters/voxel_grid.h>

滤波代码示例:

cout << "->正在体素下采样..." << endl;
	pcl::VoxelGrid<pcl::PointXYZ> vg;		//创建滤波器对象
	vg.setInputCloud(cloud);				//设置待滤波点云
	vg.setLeafSize(0.05f, 0.05f, 0.05f);	//设置体素大小
	vg.filter(*cloud_filtered);	 //执行滤波,保存滤波结果于cloud_filtered

使用步骤:

读入点云→创建滤波器对象→设置体素大小→执行滤波→保存滤波点云

在这里插入图片描述

3、均匀采样 uniformSampling

原理:对点云数据创建一个三维体素栅格,然后,在每个体素保留一个最接近体素中心的点,代替体素中所有点。

头文件为:

#include <pcl/keypoints/uniform_sampling.h>

滤波代码实例:

	cout << "->正在均匀采样..." << endl;
	pcl::UniformSampling<pcl::PointXYZ> us;	//创建滤波器对象
	us.setInputCloud(cloud);				//设置待滤波点云
	us.setRadiusSearch(0.05f);				//设置滤波球体半径
	us.filter(*cloud_filtered);		//执行滤波,保存滤波结果于cloud_filtered

使用步骤:

读入点云→创建滤波器对象→设置滤波球体半径→执行滤波→保存滤波点云

4、统计滤波器 statisticalOutlierRemoval

原理:对每一点的邻域进行统计分析,基于点到所有邻近点的距离分布特征,过滤掉一些不满足要求的离群点。该算法对整个输入进行两次迭代:在第一次迭代中,它将计算每个点到最近k个近邻点的平均距离,得到的结果符合高斯分布。接下来,计算所有这些距离的平均值 μ 和标准差 σ 以确定距离阈值 thresh_d ,且 thresh_d = μ ± k·σ。 k为标准差乘数。在下一次迭代中,如果这些点的平均邻域距离分别低于或高于该阈值,则这些点将被分类为内点或离群点。

头文件为:

#include <pcl/filters/statistical_outlier_removal.h>

滤波代码实例:

cout << "->正在进行统计滤波..." << endl;
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;	//创建滤波器对象
	sor.setInputCloud(cloud);				//设置待滤波点云
	sor.setMeanK(50);						//设置查询点近邻点的个数
	sor.setStddevMulThresh(1.0);			//设置标准差乘数,来计算是否为离群点的阈值
	//sor.setNegative(true);				//默认false,保存内点;true,保存滤掉的离群点
	sor.filter(*cloud_filtered);	//执行滤波,保存滤波结果于cloud_filtered

使用步骤:

读入点云→创建滤波器对象→设置离群点阈值→执行统计滤波→保存滤波点云

在这里插入图片描述

5、半径滤波器 RadiusOutlierRemoval

原理:对整个输入迭代一次,对于每个点进行半径R邻域搜索,如果邻域点的个数低于某一阈值,则该点将被视为噪声点并被移除。

头文件为:

#include <pcl/filters/radius_outlier_removal.h>

滤波代码示例:

	cout << "->正在进行半径滤波..." << endl;
	pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror;	//创建滤波器对象
	ror.setInputCloud(cloud);						//设置待滤波点云
	ror.setRadiusSearch(0.02);						//设置查询点的半径范围
	ror.setMinNeighborsInRadius(5);	//设置判断是否为离群点的阈值,即半径内至少包括的点数
	//ror.setNegative(true);	//默认false,保存内点;true,保存滤掉的外点
	ror.filter(*cloud_filtered);	//执行滤波,保存滤波结果于cloud_filtered

使用步骤:

读入点云→创建半径滤波器对象→设置离群点阈值→执行下采样→保存采样结果
没有离散的点效果不明显
6、条件滤波器 conditionRemoval

筛选满足特定条件的点云数据。有两种类型的条件:

[1]ConditionAnd: 所有条件都要满足

[2]ConditionOr: 满足一个条件即可
可以设置一个或多个条件对象,并为条件对象添加比较算子。条件比较算子包含三项:

[1]名称:对应于点云XYZ字段名称、RGB颜色空间、HSI颜色空间中的颜色分量等。

[2]比较运算符:GT、GE、LT、LE、EQ

[3]值:即要比较的名称的数值

比较运算符罗列:

运算符含义
GTgreater than 大于
GEgreater than or equal 大于等于
LTless than 小于
LEless than or equal 小于等于
EQequal 等于

头文件为:

#include <pcl/filters/conditional_removal.h>

滤波代码为:

cout << "->正在进行条件滤波..." << endl;
	/*创建条件限定下的滤波器*/
	pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>());//创建条件定义对象range_cond
	//为条件定义对象添加比较算子
range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
pcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::GT, -0.1)));//添加在x字段上大于 -0.1 的比较算子
	range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
		pcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::LT, 1.0)));//添加在x字段上小于 1.0 的比较算子
	pcl::ConditionalRemoval<pcl::PointXYZ> cr;	//创建滤波器对象
	cr.setCondition(range_cond);				//用条件定义对象初始化
	cr.setInputCloud(cloud);					//设置待滤波点云
	//cr.setKeepOrganized(true);				//设置保持点云的结构
	//cr.setUserFilterValue(5);					//将过滤掉的点用(5,5,5)代替
	cr.filter(*cloud_filtered);					//执行滤波,保存滤波结果于cloud_filtered

setKeepOrganized(true) 解释:

保持点云结构,即有序点云经过滤波后,仍能够保持有序性。*

*setKeepOrganized默认false,即直接将滤除的点删除,从而可能改变点云的组织结构。is_dense: 1

若设置为true,再通过setuserFilterValue设置一个指定的值,被滤除的点将会被该值代替;不进行setuserFilterValue设置,则默认用nan填充被滤除的点。is_dense: 0;

使用步骤:

读入点云→创建条件对象→添加比较算子→创建条件限定下的滤波器对象→执行滤波→保存滤波结果

在这里插入图片描述
7、索引提取 extractIndices

原理:从原始点云中提取一组索引对应的点云子集,前提是要获取点云索引集合。

头文件为:

#include <pcl/filters/extract_indices.h>

滤波代码实例:

cout << "->正在进行点云平面子集提取..." << endl;
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());	//创建分割时所需要的模型系数对象coefficients
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices());				//创建存储内点的点索引集合对象inliers
	pcl::SACSegmentation<pcl::PointXYZ> seg;								//创建分割对象
	seg.setOptimizeCoefficients(true);										//可选,对估计的模型参数进行优化处理
	seg.setModelType(pcl::SACMODEL_PLANE);									//设置分割模型类别
	seg.setMethodType(pcl::SAC_RANSAC);										//设置随即参数估计方法
	seg.setMaxIterations(1000);												//设置最大迭代次数
	seg.setDistanceThreshold(0.01);											//设置判断是否为模型内点的距离阈值
		/*平面点云提取*/
	///从点云中分割最大平面组成部分
	seg.setInputCloud(cloud);//设置输入点云,待分割
	seg.segment(*inliers, *coefficients);//引发分割实现:存储分割结果到点集合inliers;存储平面模型系数coefficients
	
	pcl::ExtractIndices<pcl::PointXYZ> extract;	//创建点云提取对象
	extract.setInputCloud(cloud);				//设置输入点云
	extract.setIndices(inliers);				//设置分割后的内点inliers为需要提取的点集
	extract.setNegative(false);					//设置提取内点而非外点,默认false
	extract.filter(*cloud_filtered);			//提取点集并存储到 cloud_filtered

使用步骤:

读入点云→平面分割获取索引集合→创建点云索引提取对象→执行索引提取→保存提取点云

在这里插入图片描述
8、投影滤波器 projectInliers

原理:将点投影到一个参数化模型上,这个参数化模型可以是平面、圆球、圆柱、锥形等进行投影滤波。

头文件为:

#include <pcl/filters/project_inliers.h>

滤波代码实例:

	cout << "->正在平面模型投影..." << endl;
	//创建 Ax+By+Cz=0 平面
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
	coefficients->values.resize(4);	//设置模型系数的大小
	coefficients->values[0] = 1.0;	//x系数
	coefficients->values[1] = 1.0;	//y系数
	coefficients->values[2] = 1.0;	//z系数
	coefficients->values[3] = 0.0;	//常数项
	//投影滤波
	pcl::ProjectInliers<pcl::PointXYZ> proj;//创建投影滤波器对象
	proj.setModelType(pcl::SACMODEL_PLANE);	//设置对象对应的投影模型
	proj.setInputCloud(cloud);				//设置输入点云
	proj.setModelCoefficients(coefficients);//设置模型对应的系数
	proj.filter(*cloud_projected);			//执行投影滤波,存储结果于cloud_projected

投影模型:

  • 平面模型:SACMODEL_PLANE
  • 线模型:SACMODEL_LINE
  • 平面上的二维圆:SACMODEL_CIRCLE2D
  • 平面上的三维圆:SACMODEL_CIRCLE3D
  • 球体模型:SACMODEL_SPHERE
  • 圆柱模型:SACMODEL_CYLINDER
  • 圆锥模型:SACMODEL_CONE
  • 圆环模型:SACMODEL_TORUS
  • 平行于给定轴的一种线模型:SACMODEL_PARALLEL_LINE
  • 垂直于指定轴的平面模型:SACMODEL_PERPENDICULAR_PLANE
  • 三维棒分割模型:SACMODEL_STICK

使用步骤:

读入点云→创建参数化模型→设置模型系数→执行投影滤波→保存投影点云

在这里插入图片描述

9、模型滤波器 modelOutlierRemoval

原理:根据点到模型的距离,设置距离阈值过滤非模型点。

头文件为:

#include <pcl/filters/model_outlier_removal.h>

滤波代码实例:

	cout << "->正在模型滤波..." << endl;
	//设置模型系数
	pcl::ModelCoefficients model_coeff;
	model_coeff.values.resize(4);
	model_coeff.values[0] = 1.0;
	model_coeff.values[1] = 1.0;
	model_coeff.values[2] = 1.0;
	model_coeff.values[3] = 0.0;
	///模型滤波
	pcl::ModelOutlierRemoval<pcl::PointXYZ> filter;	//创建模型滤波器对象
	filter.setModelCoefficients(model_coeff);		//为模型对象添加模型系数
	filter.setThreshold(0.1);						//设置判断是否为模型内点的阈值
	filter.setModelType(pcl::SACMODEL_PLANE);		//设置模型类别
	filter.setInputCloud(cloud);					//输入待滤波点云
	filter.setNegative(false);						//默认false,提取模型内点;true,提取模型外点
	filter.filter(*cloud_filtered);					//执行模型滤波,保存滤波结果于cloud_filtered

使用步骤:

读入点云→设置模型系数→创建模型滤波器对象→执行模型滤波→保存滤波结果
在这里插入图片描述
10、双边滤波 BilateralFilter

原理:class pcl::BilateralFilter< PointT > 类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理(所以在用这个函数的时候是需要注意自己输入点云的数据格式的,需要包含点云的强度信息)。

头文件为:

#include <pcl/filters/bilateral.h>

滤波代码实例:

pcl::search::KdTree<pcl::PointXYZI>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZI>);
	pcl::BilateralFilter<pcl::PointXYZI> bf;
	bf.setInputCloud(cloud);
	bf.setSearchMethod(tree);
	bf.setHalfSize(0.1);	// 设置高斯双边滤波窗口的一半大小,即搜索半径。
	bf.setStdDev(0.03);		// 设置标准差参数
	bf.filter(*outcloud);
  • 40
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCL(Point Cloud Library)是一个用于处理点云数据的开源库。半径滤波PCL中常用的点云滤波方法之一,用于去除离群点和平滑点云数据。 半径滤波的过程如下: 1. 定义一个搜索半径(radius)来确定每个点的邻域范围。 2. 对于点云中的每个点,搜索其邻域内的所有点。 3. 计算邻域内所有点的平均值或中值,并将该值作为当前点的新坐标。 4. 重复步骤2和步骤3,直到处理完所有的点。 5. 可选地,可以使用统计学方法(例如标准差)来进一步排除离群点。 使用PCL进行半径滤波的示例代码如下: ```cpp #include <pcl/point_cloud.h> #include <pcl/filters/radius_outlier_removal.h> int main() { // 创建输入点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 读取或生成点云数据 // 创建半径滤波对象 pcl::RadiusOutlierRemoval<pcl::PointXYZ> radius_filter; radius_filter.setInputCloud(cloud); radius_filter.setRadiusSearch(0.1); // 设置半径搜索范围 radius_filter.setMinNeighborsInRadius(10); // 设置邻居点的最小数量 // 执行半径滤波 pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>); radius_filter.filter(*filtered_cloud); return 0; } ``` 上述代码中,我们首先创建了一个输入点云对象`cloud`,然后创建了`RadiusOutlierRemoval`对象`radius_filter`来进行半径滤波。设置半径搜索范围和邻居点的最小数量后,调用`filter`方法执行滤波操作,并将结果保存在`filtered_cloud`中。 需要注意的是,半径滤波只能去除离群点和平滑点云数据,对于边缘保持和细节保持较差。在实际应用中,可以根据具体需求调整半径和邻居点的数量来获取理想的滤波效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值