PCL学习笔记:点云滤波汇总

转载自:https://blog.csdn.net/weixin_46098577/article/details/114385690

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

    点云数据密度不规则需要平滑
    因遮挡等问题噪声的离群点需要去除
    数据冗余需要下采样
    噪声数据需要去除

对应的方法如下:

    按具体给定的规则过滤点
    通过滤波算法修改点的部分属性
    点云数据下采样

下面对PCL各种滤波方法做一些归纳总结,方便日后使用。

一、直通滤波

针对点云某一维度,去掉指定范围内(或外)的点。

流程:读入点云→创建滤波器对象→设置滤波字段范围→执行滤波→保存滤波结果

#include <pcl/filters/passthrough.h>

 



二、VoxelGrid体素滤波器

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

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

#include <pcl/filters/voxel_grid.h

滤波前后对比

 

 

三、UniformSampling均匀采样

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

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

#include <pcl/keypoints/uniform_sampling.h>
滤波前后对比

 

 

四、StatisticalOutlierRemoval统计滤波器

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

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

#include <pcl/filters/statistical_outlier_removal.h>
滤波前后对比

 

 

五、RadiusOutlierRemoval半径滤波器

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

流程:读入点云→创建半径滤波器对象→设置离群点阈值→执行下采样→保存采样结果

#include <pcl/filters/radius_outlier_removal.h>
滤波前后对比

 

 

 

六、ConditionRemoval条件滤波器

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

 ConditionAnd: 所有条件都要满足
ConditionOr: 满足一个条件即可

可以设置一个或多个条件对象,并为条件对象添加比较算子。条件比较算子包含三项:

(1)名称:对应于点云XYZ字段名称、RGB颜色空间、HSI颜色空间中的颜色分量等。
(2) 比较运算符:GT、GE、LT、LE、EQ

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

switch (this->op_)
  {
    case pcl::ComparisonOps::GT :
      return (compare_result > 0);
    case pcl::ComparisonOps::GE :
      return (compare_result >= 0);
    case pcl::ComparisonOps::LT :
      return (compare_result < 0);
    case pcl::ComparisonOps::LE :
      return (compare_result <= 0);
    case pcl::ComparisonOps::EQ :
      return (compare_result == 0);
    default:
      PCL_WARN ("[pcl::FieldComparison::evaluate] unrecognized op_!\n");
      return (false);
  }

值:即要比较的名称的数值

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

#include <pcl/filters/conditional_removal.h>
滤波前后对比

setKeepOrganized(true) 解释:

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

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

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

七、ExtractIndices索引提取

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

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

#include <pcl/filters/extract_indices.h>
滤波前后对比

 

八、投影滤波器

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

参数化模型投影点云,以平面投影为例:读入点云→创建参数化模型→设置模型系数→执行投影滤波→保存投影点云

#include <pcl/filters/project_inliers.h>

投影前后对比

 

九、ModelOutlierRemoval模型滤波器

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

流程:读入点云→设置模型系数→创建模型滤波器对象→执行模型滤波→保存滤波结果

滤波前后对比

 

十、空间裁剪滤波

10.1 CropHull滤波器

获取点云在 3D 封闭曲面上或 2D 封闭多边形内或外部的点。

流程:读入点云→设置封闭范围顶点→创建凸包对象→执行CropHull滤波→保存滤波点云

需要注意的是 ,setDimension()和CH.setDim()的维度应保持一致

    当维度设置为2时,封闭区域为2D封闭多边形,只有X和Y两个维度。因此,该封闭多边形在三维空间中表示为垂直于XOY面的竖直曲面。得到的是曲面内部或外部的点云。
    当维度设置为3时,封闭区域为3D封闭曲面,仅得到位于该封闭曲面上的点。

十一 、BilateralFilter 双边滤波器

class pcl::BilateralFilter< PointT > 类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理(所以在用这个函数的时候是需要注意自己输入点云的数据格式的,需要包含点云的强度信息)
#include <pcl/filters/bilateral.h>
注:只是代码跑通,并不适用于1.pcd文件(1.pcd文件只有XYZ字段,没有强度字段)

 

posted @ 2022-03-14 21:59  楸壳  阅读(4201)  评论(0编辑  收藏  举报