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

PCl 滤波汇总

1、直通滤波 passThrough

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

头文件为:

#include

滤波代码实例:

	// Create the filtering object
	pcl::PassThrough 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的范围之内的点将被保留,范围之外的点将被舍弃,实现直通滤波的功能

PCL滤波大全、原理+代码实例+操作步骤_第1张图片

2、体素滤波器 voxelGrid

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

头文件为:

#include 

滤波代码示例:

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

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第2张图片

3、均匀采样 uniformSampling

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

头文件为:

#include 

滤波代码实例:

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

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第3张图片

4、统计滤波器 statisticalOutlierRemoval

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

头文件为:

#include 

滤波代码实例:

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

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第4张图片

5、半径滤波器 RadiusOutlierRemoval

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

头文件为:

#include 

滤波代码示例:

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

使用步骤:

读入点云→创建半径滤波器对象→设置离群点阈值→执行下采样→保存采样结果
PCL滤波大全、原理+代码实例+操作步骤_第5张图片
6、条件滤波器 conditionRemoval

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

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

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

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

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

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

比较运算符罗列:

运算符 含义
GT greater than 大于
GE greater than or equal 大于等于
LT less than 小于
LE less than or equal 小于等于
EQ equal 等于

头文件为:

#include 

滤波代码为:

cout << "->正在进行条件滤波..." << endl;
	/*创建条件限定下的滤波器*/
	pcl::ConditionAnd::Ptr range_cond(new pcl::ConditionAnd());//创建条件定义对象range_cond
	//为条件定义对象添加比较算子
range_cond->addComparison(pcl::FieldComparison::ConstPtr(new
pcl::FieldComparison("x", pcl::ComparisonOps::GT, -0.1)));//添加在x字段上大于 -0.1 的比较算子
	range_cond->addComparison(pcl::FieldComparison::ConstPtr(new
		pcl::FieldComparison("x", pcl::ComparisonOps::LT, 1.0)));//添加在x字段上小于 1.0 的比较算子
	pcl::ConditionalRemoval 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;

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第6张图片
7、索引提取 extractIndices

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

头文件为:

#include 

滤波代码实例:

cout << "->正在进行点云平面子集提取..." << endl;
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());	//创建分割时所需要的模型系数对象coefficients
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices());				//创建存储内点的点索引集合对象inliers
	pcl::SACSegmentation 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 extract;	//创建点云提取对象
	extract.setInputCloud(cloud);				//设置输入点云
	extract.setIndices(inliers);				//设置分割后的内点inliers为需要提取的点集
	extract.setNegative(false);					//设置提取内点而非外点,默认false
	extract.filter(*cloud_filtered);			//提取点集并存储到 cloud_filtered

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第7张图片
8、投影滤波器 projectInliers

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

头文件为:

#include 

滤波代码实例:

	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 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

使用步骤:

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

PCL滤波大全、原理+代码实例+操作步骤_第8张图片

9、模型滤波器 modelOutlierRemoval

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

头文件为:

#include 

滤波代码实例:

	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 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

使用步骤:

读入点云→设置模型系数→创建模型滤波器对象→执行模型滤波→保存滤波结果
PCL滤波大全、原理+代码实例+操作步骤_第9张图片
10、双边滤波 BilateralFilter

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

头文件为:

#include 

滤波代码实例:

pcl::search::KdTree::Ptr tree(new pcl::search::KdTree);
	pcl::BilateralFilter bf;
	bf.setInputCloud(cloud);
	bf.setSearchMethod(tree);
	bf.setHalfSize(0.1);	// 设置高斯双边滤波窗口的一半大小,即搜索半径。
	bf.setStdDev(0.03);		// 设置标准差参数
	bf.filter(*outcloud);

你可能感兴趣的:(PCL点云,c++,计算机视觉)