[PCL] 点云滤波

所有的代码和点云文件:source

在获取点云数据时,由于设备精度,操作者经验,环境因素带来的影响,以及电磁波的衍射特性,被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中讲不可避免的出现一些噪声。在点云处理流程中滤波处理作为预处理的第一步,对后续的影响比较大,只有在滤波预处理中将噪声点 ,离群点,孔洞,数据压缩等按照后续处理定制,才能够更好的进行配准,特征提取,曲面重建,可视化等后续应用处理。

PCL中点云滤波模块提供了很多灵活实用的滤波处理算法,例如:双边滤波、高斯滤波、条件滤波、直通滤波、基于随机采样一致性滤波,PCL中点云滤波的方案PCL中总结了几种需要进行点云滤波处理情况,这几种情况分别如下:

  1. 点云数据密度不规则需要平滑
  2. 因为遮挡等问题造成离群点需要去除
  3. 大量数据需要下采样
  4. 噪声数据需要去除

对应的方案如下

  1. 按照给定的规则限制过滤去除点
  2. 通过常用滤波算法修改点的部分属性
  3. 对数据进行下采样

pcl::ApproximateVoxelGrid< PointT > 类ApproximateVoxelGrid根据给定的点云形成三维体素栅格,并利用所有体素的中心点近似体素中包含的点集,这样完成下采样得到滤波结果,该类比较合适对海量点云数据在处理前进行压缩,提高算法效率

pcl::BilateralFilter< PointT > 类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,双边滤波算法是通过取临近采样点和加权平均来修正当前采样点的位置,从而达到滤波效果,同时也会有选择剔除与当前采样点“差异”太大的相邻采样点,从而保持原特征的目的

pcl::BoxClipper3D< PointT > 实现用一个原点为中心,XYZ各个方向尺寸为2 经过用户指定的仿射变换的立方体进行空间裁剪,通过设置一个仿射变换矩阵先对立方体进行变换处理,之后输出仿射变换后落在该立方体内的点

pcl::Clipper3D< PointT > 是3D空间裁剪对象的基类

pcl::ConditionalRemoval< PointT > 实现过滤满足一定的条件的点云数据,非常灵活,可以设置滤波条件

pcl::filters::Convolution< PointIn, PointOut > 实现卷积滤波处理

pcl::filters::GaussianKernel< PointInT, PointOutT > 是基于高斯核的卷积滤波实现 高斯滤波相当于一个具有平滑性能的低通滤波器

pcl::filters::GaussianKernelRGB< PointInT, PointOutT > 是附加RGB通道基于高斯核的卷积滤波实现,不仅考虑空间XYZ而且考虑RGB

1 直通滤波

class pcl::PassThrough< PointT >

如果使用线结构光扫描的方式采集点云,必然物体沿z向分布较广,但x,y向的分布处于有限范围内。 此时可使用直通滤波器,确定点云在x或y方向上的范围,可较快剪除离群点,达到第一步粗处理的目的。

实例:

// 创建点云对象指针

pcl::PointCloud::Ptr cloud (new pcl::PointCloud);

pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);

// 原点云获取后进行滤波

pcl::PassThrough pass;// 创建滤波器对象

pass.setInputCloud (cloud); //设置输入点云

pass.setFilterFieldName ("z");//滤波字段名被设置为Z轴方向

pass.setFilterLimits (0.0, 1.0);//可接受的范围为(0.0,1.0)

//pass.setFilterLimitsNegative (true);//设置保留范围内还是过滤掉范围内 true:过滤 false:保留

pass.filter (*cloud_filtered); //执行滤波,保存过滤结果在cloud_filtered

效果:

[PCL] 点云滤波_第1张图片

可以看出,直通滤波令一定范围内的点云数据保留或者被过滤掉了。

 2 体素网格滤波

class pcl::VoxelGrid< PointT > 

体素格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。点云几何结构 不仅是宏观的几何外形,也包括其微观的排列方式,比如横向相似的尺寸,纵向相同的距离。 随机下采样虽然效率比体素滤波器高,但会破坏点云微观结构。

使用体素化网格方法实现下采样,即减少点的数量,精简点云数据,并同时保存点云的形状特征,在提高配准、曲面重建、形状识别等算法速度中非常实用,PCL是实现的VoxelGrid类通过输入的点云数据创建一个3D体素网格(将体素网格看作空间中的一组小3D框),容纳后每个体素内用体素中所有点的重心来近似显示体素中其他点,这样该体素内所有点都用一个重心点最终表示,对于所有体素处理后得到的过滤后的点云,这种方法比用体素中心逼近的方法更慢,但是对于采样点对应曲面的表示更为准确。

示例:

// 创建点云对象指针

pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());

pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());

// 源点云读取获取后

pcl::VoxelGrid sor; //创建滤波对象

sor.setInputCloud (cloud);     //设置需要过滤的点云(指针)给滤波对象

sor.setLeafSize (0.01f, 0.01f, 0.01f);   //设置滤波时创建的体素体积为1cm的立方体

sor.filter (*cloud_filtered);   //执行滤波处理,存储输出

效果:

[PCL] 点云滤波_第2张图片

[PCL] 点云滤波_第3张图片

[PCL] 点云滤波_第4张图片

原始点云与滤波后的点云可视化结果,明显的可以看出来,点的密度大小与整齐程度不同,虽然处理后的数据量大大减小,但是很明显所含有的形状特征和空间结构信息与原始点云差不多。

3 统计离群删除滤波

class pcl::StatisticalOutlierRemoval< PointT > 

使用统计分析技术,从一个点云数据中集中移除测量噪声点(也就是离群点)。比如:激光扫描通常会产生密度不均匀的点云数据集,另外测量中的误差也会产生稀疏的离群点,使效果不好,估计局部点云特征(例如采样点处法向量或曲率变化率)的运算复杂,这会导致错误的数值,反过来就会导致点云配准等后期的处理失败。

解决办法:每个点的邻域进行一个统计分析,并修剪掉一些不符合一定标准的点,稀疏离群点移除方法基于在输入数据中对点到临近点的距离分布的计算,对每一个点,计算它到它的所有临近点的平均距离,假设得到的结果是一个高斯分布,其形状是由均值和标准差决定,平均距离在标准范围之外的点,可以被定义为离群点并可从数据中去除。

示例:

// 创建点云对象指针

pcl::PointCloud::Ptr cloud (new pcl::PointCloud);

pcl::PointCloud::Ptr cloud_filtered (new pcl::PointCloud);

// 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1这意味着如果一个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来

pcl::StatisticalOutlierRemoval sor;//创建滤波器对象

sor.setInputCloud (cloud); //设置待滤波的点云

sor.setMeanK (50);  //设置在进行统计时考虑查询点临近点数

sor.setStddevMulThresh (1.0);  //设置判断是否为离群点的阀值

sor.filter (*cloud_filtered);  //存储

效果:

处理的效果如下图,分别是原点云、处理后的点云、离群点集。

[PCL] 点云滤波_第5张图片

                                                                                         原点云数据

[PCL] 点云滤波_第6张图片

                                                                                  统计离群删除后的优化点云

[PCL] 点云滤波_第7张图片

                                                                                              离群点集

4 投影滤波

class pcl::ProjectInliers< PointT > 

将点投影到一个参数化模型上(平面或者球体等),参数化模型通过一组参数来设定,对于平面来说使用其等式形式。在PCL中有特意存储常见模型系数的数据结构。

使用Point Cloud中的模型和一组inlier指数将它们投影到单独的PointCloud中。使用参数化模型投影点云,如何将点投影到一个参数化模型上(平面或者球体等),参数化模型通过一组参数来设定,对于平面来说使用其等式形式。在PCL中有特定存储常见模型系数的数据结构。

[PCL] 点云滤波_第8张图片

运行结果说明3D点云已经被投影到xy坐标的平面上。

5 双边滤波

class pcl::BilateralFilter< PointT >

实现点云的双边滤波,该类的实现利用的并非XYZ字段的数据进行, 而是利用强度数据进行双边滤波算法的实现, 所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,双边滤波算法是通过取临近采样点和加权平均来修正当前采样点的位置,从而达到滤波效果,同时也会有选择剔除与当前采样点“差异”太大的相邻采样点,从而保持原特征的目的。

6 空间裁剪

有以下几种空间裁剪。

pcl::Clipper3D

pcl::BoxClipper3D

pcl::CropBox

pcl::CropHull 剪裁并形成封闭曲面

7 条件离群点删除

class pcl::ConditionalRemoval< PointT >

过滤满足特定条件的数据。 可以一次删除满足对输入的点云设定的一个或多个条件指标的所有的数据点,删除点云中不符合用户指定的一个或者多个条件的数据点,用户必须为ConditionalRemoval提供条件。 有两种类型的条件:ConditionAnd和ConditionOr。

8 卷积滤波

class pcl::filters::Convolution< PointIn, PointOut >

实现将两个函数通过数学运算产生第三个函数,该类提供点云的行,列和单独的卷积操作。 只有有组织后者是有序的点云才允许使用列和单独的卷积。

可以设定不同的卷积核,有以下几种操作:

pcl::filters::Convolution

pcl::filters::ConvolvingKernel

pcl::filters::GaussianKernel< PointInT, PointOutT >

pcl::filters::GaussianKernelRGB< PointInT, PointOutT >

pcl::PointCloud::Ptr input_cloud (new pcl::PointCloud);

pcl::PointCloud::Ptr kernel_cloud (new pcl::PointCloud);

pcl::PointCloud::Ptr output_cloud (new pcl::PointCloud);

9 点云索引提取

 class pcl::ExtractIndices< PointT >

从点云中提取一组索引。

案例:

基于某一分割算法提取点云中的一个子集,用于点云分割。

中值滤波

class pcl::MedianFilter< PointT >

示例:

//中值滤波器
pcl::MedianFilter fbf;
fbf.setInputCloud (cloud_in);
fbf.setMaxAllowedMovement (max_allowed_movement_);
fbf.setWindowSize (window_size_);
fbf.filter (*cloud_out);

法向量重定义

class pcl::NormalRefinement< NormalT >

杂乱的法向量经过处理后会具有一致性,该类通过迭代地更新其邻域中所有法线的(加权)均值的每个法线来细化一组已经估计的法线。 目的是重复使用与估计原始法线时相同的点对应关系,以避免重复最近邻搜索。

 

 

 

你可能感兴趣的:(pcl)