点云滤波算法学习

↘锁芯ラ 提交于 2019-12-15 07:49:42

本文参考如下博客内容,在此对原博客作者表示感谢。

  1. 点云滤波简介: https://www.cnblogs.com/zhaobinyouth/p/6196358.html
  2. 点云滤波—直通滤波器:https://blog.csdn.net/wolfcsharp/article/details/93195621
  3. 点云滤波—体素网格滤波器:https://blog.csdn.net/wolfcsharp/article/details/93198320
  4. 点云滤波—统计滤波器:https://blog.csdn.net/wolfcsharp/article/details/93203442
  5. PCL 几种滤波方法:https://blog.csdn.net/qq_39482438/article/details/81110036
  6. Bilateral Filters(双边滤波算法)原理及实现:https://blog.csdn.net/piaoxuezhong/article/details/78302920

1 点云滤波和信号处理滤波

点云滤波是点云处理的基本步骤,也是进行 high level 三维图像处理之前必须要进行的预处理。其作用类似于信号处理中的滤波,但实现手段却和信号处理不一样。我认为原因有以下几个方面:

  • 点云不是函数,对于复杂三维外形其x,y,z之间并非以某种规律或某种数值关系定义。所以点云无法建立横纵坐标之间的联系。
  • 点云在空间中是离散的。和图像,信号不一样,并不定义在某个区域上,无法以某种模板的形式对其进行滤波。换言之,点云没有图像与信号那么明显的定义域。
  • 点云在空间中分布很广泛。历整个点云中的每个点,并建立点与点之间相互位置关系成了最大难点。不像图像与信号,可以有迹可循。
  • 点云滤波依赖于几何信息,而不是数值关系

综上所述,点云滤波只在抽象意义上与信号,图像滤波类似。因为滤波的功能都是突出需要的信息。

2 常用滤波器及选择策略

PCL常规滤波手段均进行了很好的封装。对点云的滤波通过调用各个滤波器对象来完成。

主要的滤波器有直通滤波器体素网格滤波器统计滤波器半径滤波器 等。不同特性的滤波器构成了较为完整的点云前处理族,并组合使用完成任务。实际上,滤波手段的选择和采集方式是密不可分的

  • 如果使用线结构光扫描的方式采集点云,必然物体沿z向分布较广,但x,y向的分布处于有限范围内。此时可使用直通滤波器,确定点云在x或y方向上的范围,可较快剪除离群点,达到第一步粗处理的目的。
  • 如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。过多的点云数量会对后续分割工作带来困难。体素网格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。点云几何结构不仅是宏观的几何外形,也包括其微观的排列方式,比如横向相似的尺寸,纵向相同的距离。随机下采样虽然效率比体素滤波器高,但会破坏点云微观结构。
  • 统计滤波器用于去除明显离群点(离群点往往由测量噪声引入)。其特征是在空间中分布稀疏,可以理解为:每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除3∑之外的点。
  • 半径滤波器与统计滤波器相比更加简单粗暴。以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是圆的半径和圆内点的数目都需要人工指定。

实际上点云滤波的手段和传统的信号滤波与图像滤波在自动化程度,滤波效果上还有很大的差距。学者大多关注图像识别与配准算法在点云处理方面的移植,而对滤波算法关注较少。其实点云前处理对测量精度与识别速度都有很大影响。

3 滤波器介绍

3.1 直通滤波器(PassThrough filter)

工作原理

直通滤波器,顾名思义,就是在点云的指定维度上设置一个阈值范围,将这个维度上的数据分为在阈值范围内与不在阈值范围内,从而选择过滤与否。

适用对象

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

pcl核心代码实现

pcl::PassThrough<pcl::PointXYZ> pass;	//创建直通滤波器对象
pass.setInputCloud(pointCloud_raw);		//设置输入的点云
pass.setFilterFieldName("z");           //设置过滤时所需要点云类型为Z字段
pass.setFilterLimits(-0.1, 10);         //设置在过滤字段的范围
pass.setFilterLimitsNegative(true);     //设置保留还是过滤掉字段范围内的点,设置为true表示过滤掉字段范围内的点
pass.filter(*pointCloud_filter);		//执行滤波

3.2 体素网格滤波器(VoxelGrid Filter)

工作原理

体素的概念类似于像素,像素是二维的一个个点,而体素则是三维的一个个小空间。在输入点云数据上创建一个个3D体素网格(将体素网格视为一组空间中的微小3D小空间)。 然后,在每个体素中,所有存在的点将用它们的质心近似。 这种方法比用体素的中心直接代替它们要慢一些,但它可以更准确地保持宏观的几何外形

适用对象

如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。过多的点云数量会对后续分割工作带来困难。体素网格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。点云几何结构不仅是宏观的几何外形,也包括其微观的排列方式,比如横向相似的尺寸,纵向相同的距离。随机下采样虽然效率比体素网格滤波器高,但会破坏点云微观结构。

pcl核心代码实现

pcl::VoxelGrid<pcl::PCLPointCloud2> sor;		//创建体素滤波器对象
sor.setInputCloud (cloud);					//设置输入的点云
sor.setLeafSize (0.05f, 0.05f, 0.05f);		//设置体素大小为5cm*5cm*5cm
sor.filter (*cloud_filtered);					//执行滤波

3.3 统计滤波器(Statistical Outlier Removal)

工作原理

明显离群点的特征是在空间中分布稀疏,可以理解为:每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离,(假设得到的结果是一个高斯分布,其形状是由均值和标准差决定),那么平均距离在标准范围之外的点,可以被定义为离群点并从数据中去除。给定均值与方差,可剔除方差在3σ之外的点。

适用对象

统计滤波器主要用于滤除点云中的离群点(离群点往往由测量噪声引入)。
激光扫描通常生成具有不同点密度的点云数据集。此外,测量误差会导致稀疏异常值,从而进一步破坏点云的表达准确性。使得局部点云特征(例如表面法线或曲率变化)的估计变得非常复杂,这往往导致错误的估计结果,进而导致点云的高层应用表现不佳。

pcl核心代码实现

pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建统计滤波器对象 
sor.setInputCloud(pointCloud_raw);         			 //设置输入的点云
sor.setMeanK(50);                 					 //设置KNN的k值
sor.setStddevMulThresh(1.0);      				     //设置标准偏差乘数为1.0
sor.filter(*pointCloud_filter);          			 //执行滤波
//说明:设置标准偏差乘数为1.0,意味着1个标准差以上就是离群点
//即那些距离大于(平均距离+或者-一个标准偏差)的点将被标记为离群值并被删除。
//根据高斯分布的数学表达,均值的一个标准差之内的分布可以达到总体的95%。
//注意:这里的平均距离和标准差、方差都可以由输入的点云数据集计算出来。

3.4 半径滤波器(Radius Outlier Removal)

工作原理

半径滤波器与统计滤波器相比更加简单粗暴。以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是圆的半径和圆内点的数目都需要人工指定。

pcl核心代码实现

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
 
pcl::RadiusOutlierRemoval<pcl::PointXYZ> radiusoutlier;  //创建滤波器
radiusoutlier.setInputCloud(cloud);    //设置输入点云
radiusoutlier.setRadiusSearch(100);     //设置半径为100的范围内找临近点
radiusoutlier.setMinNeighborsInRadius(2); //设置查询点的邻域点集数小于2的删除
                                 
radiusoutlier.filter(*cloud_after_Radius);

3.5 双边滤波器(Bilateral Filters)

双边滤波器其实并不是点云滤波算法,而是图像滤波算法。只是在学点云滤波的时候刚好看到了,也记录在这里。

工作原理

双边滤波是一种非线性滤波器,它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样,双边滤波也是采用加权平均的方法,用周边像素亮度值的加权平均代表某个像素的强度,所用的加权平均基于高斯分布。最重要的是,双边滤波的权重不仅考虑了像素的欧氏距离(如普通的高斯低通滤波,只考虑了位置对中心像素的影响),还考虑了像素范围域中的辐射差异(例如卷积核中像素与中心像素之间相似程度、颜色强度,深度距离等),在计算中心像素的时候同时考虑这两个权重。

原博客作者写得很好,感兴趣可以参考如下链接:
Bilateral Filters(双边滤波算法)原理及实现:https://blog.csdn.net/piaoxuezhong/article/details/78302920

下面摘取两张图片说明双边滤波器原理。
在这里插入图片描述
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!