为什么要对点云滤波?
一般下面这几种情况需要进行点云滤波处理:
(1) 点云数据密度不规则需要平滑
(2) 因为遮挡等问题造成离群点需要去除
(3) 大量数据需要下采样
(4) 噪声数据需要去除
pcl中的方法
PCL中有一个专门的点云滤波模块,可以将噪声点去除,还可以进行点云压缩等操作,非常灵活实用,例如:双边滤波,统计滤波,条件滤波,随机采样一致性滤波等。
一般来说,滤波对应的方案有如下几种:
(1)按照给定的规则限制过滤去除点
(2) 通过常用滤波算法修改点的部分属性
(3)对数据进行下采样
-
StatisticalOutlierRemoval
顾名思义,使用统计分析技术,从一个点云数据中集中移除测量噪声点。对每个点的邻域进行统计分析,剔除不符合一定标准的邻域点。具体来说:
1.对于每个点,计算它到所有相邻点的平均距离。假设得到的分布是高斯分布,我们可以计算出一个均值 μ 和一个标准差 σ;
2.这个邻域点集中所有点与其邻域距离大于μ + std_mul * σ 区间之外的点都可以被视为离群点,并可从点云数据中去除。std_mul 是标准差倍数的一个阈值,可以自己指定。
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; //创建滤波器对象
sor.setInputCloud (cloud); //设置待滤波的点云
sor.setMeanK (50); //设置在进行统计时考虑的临近点个数
sor.setStddevMulThresh (1.0); //设置判断是否为离群点的阀值,用来倍乘标准差,也就是上面的std_mul
sor.filter (*cloud_filtered); //滤波结果存储到cloud_filtered
如上代码所示,先创建统计分析滤波器,然后设置滤波器输入是 cloud,也就是我们待处理的点云,然后设置对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1, 这意味着如果一个点的距离超出了平均距离加上一个标准差以上,则该点被标记为离群点,并将它移除。最后统计分析滤波后,输出的结果就是cloud_filtered。
-
RadiusOutlierRemoval移除离群点
一个比较简单常用的方法就是根据空间点半径范围临近点数量来滤波,对应的类名是 RadiusOutlinerRemoval,这个很容易理解,它的滤波思想非常直接,就是在点云数据中,设定每个点一定半径范围内周围至少有足够多的近邻,不满足就会被删除。比如你指定了一个半径d,然后指定该半径内至少有1个邻居,那么下图中只有黄色的点将从点云中删除。如果指定了半径内至少有2个邻居,那么黄色和绿色的点都将从点云中删除。
pcl::RadiusOutlierRemoval<pcl::PointXYZ> pcFilter; //创建滤波器对象
pcFilter.setInputCloud(cloud); //设置待滤波的点云
pcFilter.setRadiusSearch(0.8); // 设置搜索半径
pcFilter.setMinNeighborsInRadius(2); // 设置一个内点最少的邻居数目
pcFilter.filter(*cloud_filtered); //滤波结果存储到cloud_filtered
-
FastBilateralFilter、BilateralFilter
双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点 。双边滤波器的好处是可以做边缘保存。对于双边滤波不只用在图像,很多时候也会在处理点云数据的时候使用,对点云数据进行光滑处理
双边滤波算法主要用于对点云数据的小尺度起伏噪声进行平滑光顺。双边滤波应用于三维点云数据去噪,既有效地对空间三维模型表面进行降噪,又可以保持点云数据中的几何特征信息,避免三维点云数据被过渡光滑。