通过非接触法测量设备获取物体的点云数据时,由于测量设备的精度,环境因素和被测物体的表面性质的影响,点云数据中不可避免会出现一些噪声点,噪声点对后续的点云拼接、曲面重构影响十分大。必须对其进行去噪处理。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);
不同的滤波器最后的滤波效果不同。滤波过程中,总是先创建一个滤波对象,设置滤波参数,调用滤波函数对其进行滤波。