通过非接触法测量设备获取物体的点云数据时,由于测量设备的精度,环境因素和被测物体的表面性质的影响,点云数据中不可避免会出现一些噪声点,噪声点对后续的点云拼接、曲面重构影响十分大。必须对其进行去噪处理。PCL中点云滤波模块提供了很多灵活实用的滤波处理算法,例如:双边滤波,高斯滤波,条件滤波,直通滤波,基于随机采样一致性滤波等等。
1、体素网格滤波VoxelGrid

//主要代码
pcl::PointCloud<pcl::PointXYZ> ::Ptr filtered
	(new pcl::PointCloud<pcl::PointXYZ>);  //创建点云对象,用以存储滤波后点云
pcl::VoxelGrid<pcl::PointXYZ> sor;         //创建滤波对象 
sor.setInputCloud(cloud);                  //设置需要过滤的点云给滤波对象 
sor.setLeafSize(0.01f, 0.01f, 0.01f);      //设置滤波时创建的体素体积为1cm的立方体  
sor.filter(*filtered);                    //执行滤波处理,存储输出

2、统计滤波器statisticalOutlierRemoval

//主要代码
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建滤波器对象  
   sor.setInputCloud(cloud);                        //设置待滤波的点云  
   sor.setMeanK(50);                               //设置在进行统计时考虑查询点临近点数  
   sor.setStddevMulThresh(1.0);                    //设置判断是否为离群点的阀值  
   sor.filter(*cloud_filtered);                    //存储

3、直通滤波器PassThrough

//主要代码
// Create the filtering object  
	pcl::PassThrough<pcl::PointXYZ> pass;  
	pass.setInputCloud (cloud);  
	pass.setFilterFieldName ("z");  
	pass.setFilterLimits (0.0, 1.0);              //设置滤波范围
	//pass.setFilterLimitsNegative (true);  
	pass.filter (*cloud_filtered);

4、半径滤波器RadiusOutlierRemoval

//主要代码
// build the condition创建环境  
pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond (new  
 pcl::ConditionAnd<pcl::PointXYZ> ());             
//为条件定义对象添加比较算子  
range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new  
 pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0)));//添加在z轴上大于0的比较算子   
range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new  
 pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 0.8)));//添加在z轴上小于0.8的比较算子   
// build the filter创建滤波器并用条件定义对象初始化  
//pcl::ConditionalRemoval<pcl::PointXYZ> condrem (range_cond);  
//例程中的语句会报错,重载函数调用不明确,删掉(range_cond)即可  
pcl::ConditionalRemoval<pcl::PointXYZ> condrem;  
condrem.setCondition (range_cond);  
condrem.setInputCloud (cloud);  
condrem.setKeepOrganized(true);//设置保持点云的结构  
// apply filter应用滤波器  
condrem.filter (*cloud_filtered);
// Create the filtering——RadiusOutlierRemoval  
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;  
    // build the filter 创建滤波器  
    outrem.setInputCloud(cloud);  
    outrem.setRadiusSearch(0.80);//设置在0.8半径的范围内找邻近点  
    outrem.setMinNeighborsInRadius(2000);//设置查询点的邻近点集数小于2000的删除  
    // apply filter    应用滤波器  
    outrem.filter(*cloud_outrem_filtered);//执行条件滤波,存储结果到cloud_filtered
pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;    
// build the filter 创建滤波器  
outrem.setInputCloud(cloud);  
outrem.setRadiusSearch(0.8);//设置在0.8半径的范围内找邻近点  
outrem.setMinNeighborsInRadius (2);//设置查询点的邻近点集数小于2的删除  
// apply filter    应用滤波器  
outrem.filter (*cloud_filtered);//执行条件滤波,存储结果到cloud_filtered
// 创建滤波器并用条件定义对象初始化    
    //pcl::ConditionalRemoval<pcl::PointXYZ> condrem (range_cond);    
    //例程中的语句会报错,重载函数调用不明确,删掉(range_cond)即可    
    pcl::ConditionalRemoval<pcl::PointXYZ> condrem;  
    condrem.setCondition(range_cond);  
    condrem.setInputCloud(cloud);  
    condrem.setKeepOrganized(true);//设置保持点云的结构    
    // apply filter应用滤波器    
    condrem.filter(*cloud_condition_filtered);

5 、project_inliers滤波

// 创建一个系数为X=Y=0,Z=1的平面  
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());  
  coefficients->values.resize (4);  
  coefficients->values[0] = coefficients->values[1] = 0;  
  coefficients->values[2] = 1.0;  
  coefficients->values[3] = 0;  
  // 创建滤波器对象  
  pcl::ProjectInliers<pcl::PointXYZI> proj;  
  proj.setModelType (pcl::SACMODEL_PLANE);  
  proj.setInputCloud (cloud);  
  proj.setModelCoefficients (coefficients);  
  proj.filter (*cloud_projected);

6、extract_indices滤波

pcl::ExtractIndices<pcl::PointXYZ> extract;  
 extract.setInputCloud(cloud_filtered);  
 extract.setIndices(inliers);  
 extract.setNegative(false);  
  
//Write the planar inliers to disk  
 extract.filter(*cloud_plane);  
 std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size() 
 << " data points." << std::endl;  
// Remove the planar inliers, extract the rest  
 extract.setNegative(true);  
 extract.filter(*cloud_f);

不同的滤波器最后的滤波效果不同。滤波过程中,总是先创建一个滤波对象,设置滤波参数,调用滤波函数对其进行滤波。