在获取点云数据时 ,由于设备精度,操作者经验环境因素带来的影响,以及电磁波的衍射特性,被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中讲不可避免的出现一些噪声。在点云处理流程中滤波处理作为预处理的第一步,对后续的影响比较大,只有在滤波预处理中将噪声点 ,离群点,孔洞,数据压缩等按照后续处理定制,才能够更好的进行配准,特征提取,曲面重建,可视化等后续应用处理,PCL中点云滤波模块提供了很多灵活实用的滤波处理算法,例如:双边滤波,高斯滤波,条件滤波,直通滤波,基于随机采样一致性滤波,
PCL中点云滤波的方案
PCL中总结了几种需要进行点云滤波处理情况,这几种情况分别如下:
 (1)  点云数据密度不规则需要平滑
 (2) 因为遮挡等问题造成离群点需要去除
 (3) 大量数据需要下采样
 (4) 噪声数据需要去除
对应的方案如下:
 (1)按照给定的规则限制过滤去除点
 (2) 通过常用滤波算法修改点的部分属性
 (3)对数据进行下采样
双边滤波算法是通过取临近采样点和加权平均来修正当前采样点的位置,从而达到滤波效果,同时也会有选择剔除与当前采样点“差异”太大的相邻采样点,从而保持原特征的目的

Classes

pcl::ApproximateVoxelGrid< PointT >   类ApproximateVoxelGrid根据给定的点云形成三维体素栅格,并利用所有体素的中心点近似体素

中包含的点集,这样完成下采样得到滤波结果,该类比较合适对海量点云数据在处理前进行压缩,提高算法效率

class

pcl::BilateralFilter< PointT >  类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用

强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,

class

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

class

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

class

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

class

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

class

pcl::filters::ConvolvingKernel< PointInT, PointOutT >  是所有卷积核的基类

class

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

class

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

class

pcl::CropBox< PointT >    过滤掉在用户给定立方体内的点云数据

class

pcl::CropHull< PointT >   过滤在给定三维封闭曲面或二维封闭多边形内部或外部的点云数据

class

pcl::ExtractIndices< PointT >  从一个点云中提取索引

class

pcl::Filter< PointT >  是滤波模块最重要的类  其他所有的滤波模块的类都从它继承。

。。。。。。。。。。(还有很多)

应用实例

(1)在PCL 中使用直通滤波器对点云进行滤波处理

代码解析如下

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h> int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>); //生成并填充点云
cloud->width = ;
cloud->height = ;
cloud->points.resize (cloud->width * cloud->height); for (size_t i = ; i < cloud->points.size (); ++i) //填充数据
{
cloud->points[i].x = * rand () / (RAND_MAX + 1.0f);
cloud->points[i].y = * rand () / (RAND_MAX + 1.0f);
cloud->points[i].z = * rand () / (RAND_MAX + 1.0f);
} std::cerr << "Cloud before filtering: " << std::endl; //打印
for (size_t i = ; i < cloud->points.size (); ++i)
std::cerr << " " << cloud->points[i].x << " "
<< cloud->points[i].y << " "
<< cloud->points[i].z << std::endl;
/************************************************************************************
创建直通滤波器的对象,设立参数,滤波字段名被设置为Z轴方向,可接受的范围为(0.0,1.0)
即将点云中所有点的Z轴坐标不在该范围内的点过滤掉或保留,这里是过滤掉,由函数setFilterLimitsNegative设定
***********************************************************************************/
// 设置滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud (cloud); //设置输入点云
pass.setFilterFieldName ("z"); //设置过滤时所需要点云类型的Z字段
pass.setFilterLimits (0.0, 1.0); //设置在过滤字段的范围
//pass.setFilterLimitsNegative (true); //设置保留范围内还是过滤掉范围内
pass.filter (*cloud_filtered); //执行滤波,保存过滤结果在cloud_filtered std::cerr << "Cloud after filtering: " << std::endl; //打印
for (size_t i = ; i < cloud_filtered->points.size (); ++i)
std::cerr << " " << cloud_filtered->points[i].x << " "
<< cloud_filtered->points[i].y << " "
<< cloud_filtered->points[i].z << std::endl; return ();
}

由于随机生成的点云,所以每次运行结果不一样,但是都会将点云中Z坐标在(0,1)范围外的点过滤掉

(2)使用VoxelGrid滤波器对点云进行下采样

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

代码解释

voxel_grid.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h> int
main (int argc, char** argv)
{ pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ()); //点云对象的读取
pcl::PCDReader reader; reader.read ("table_400.pcd", *cloud); //读取点云到cloud中 std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
<< " data points (" << pcl::getFieldsList (*cloud) << ")."; /******************************************************************************
创建一个叶大小为1cm的pcl::VoxelGrid滤波器,
**********************************************************************************/
pcl::VoxelGrid<pcl::PCLPointCloud2> sor; //创建滤波对象
sor.setInputCloud (cloud); //设置需要过滤的点云给滤波对象
sor.setLeafSize (0.01f, 0.01f, 0.01f); //设置滤波时创建的体素体积为1cm的立方体
sor.filter (*cloud_filtered); //执行滤波处理,存储输出 std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
<< " data points (" << pcl::getFieldsList (*cloud_filtered) << ")."; pcl::PCDWriter writer;
writer.write ("table_scene_lms400_downsampled.pcd", *cloud_filtered,
Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false); return ();
}

从输出的结果可以看出,过滤后的数据量大大减小了。打印结果如下

显示的结果图可以看出对比

   

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

微信公众号号可扫描二维码一起共同学习交流

未完待续***************************88

PCL滤波介绍(1)的更多相关文章

  1. PCL滤波介绍(3)

    (1)从一个点云中提取索引 如何使用一个,基于某一分割算法提取点云中的一个子集. 代码解析 #include <iostream> #include <pcl/ModelCoeffi ...

  2. PCL滤波介绍(2)

    (1)使用statisticalOutlierRemoval滤波器移除离群点 使用统计分析技术,从一个点云数据中集中移除测量噪声点(也就是离群点)比如:激光扫描通常会产生密度不均匀的点云数据集,另外测 ...

  3. 图像处理之均值滤波介绍及C算法实现

    1 均值滤波介绍 滤波是滤波是将信号中特定波段频率滤除的操作,是从含有干扰的接收信号中提取有用信号的一种技术. 均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临 ...

  4. 图像处理之中值滤波介绍及C实现

    1 中值滤波概述 中值滤波是基于排序统计理论的一种能有效抑制噪声的非线性信号平滑处理技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值. 中值滤波的基本原理是把数字图像或数字序 ...

  5. PCL—低层次视觉—点云滤波(初步处理)

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

  6. PCL—点云滤波(初步处理)

    博客转载自:http://www.cnblogs.com/ironstark/p/4991232.html 点云滤波的概念 点云滤波是点云处理的基本步骤,也是进行 high level 三维图像处理之 ...

  7. PCL学习笔记(一)

    由于项目需要,开始学习一下HP公司的PCL打印语言,发现这方面的中文资料非常少,我做下记录也为后人提供便利. 关于PCL的介绍可以参考wiki百科 http://zh.wikipedia.org/zh ...

  8. PCL基础3.2-如何编写新的PCL类

    1.文件名为mainBilateralFilter.cpp的文件内容如下 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h ...

  9. opencv-11-中值滤波及自适应中值滤波

    开始之前 在上一篇我们实现了读取噪声图像, 然后 进行三种形式的均值滤波得到结果, 由于我们自己写的均值滤波未作边缘处理, 所以效果有一定的下降, 但是总体来说, 我们得到的结果能够说明我们的算法执行 ...

随机推荐

  1. Linux 查看文件 cat与 more 用法

    1.cat 显示文件连接文件内容的工具: cat 是一个文本文件查看和连接工具.查看一个文件的内容,用cat比较简单,就是cat 后面直接接文件名. 比如: [root@localhost ~]# c ...

  2. MetInfo PHP的CMS,目测还不错

    MetInfo PHP的CMS,目测还不错,先记录下来

  3. Android SDK不能够更新

    Adroid不能够更新,因为国内将google的服务器墙掉了,在 1) vim /etc/hosts(Windows上路径为:C:\Windows\System32\drivers\etc\hosts ...

  4. 本地搭建 Gradle 服务器,提高 Android Studio Gradle 下载速度

    AndroidStudio 更新以后,在公司网会卡在下载 Gradle 的地方,下载 Gradle 速度很慢. 看到别人的博客提供的解决办法本地搭建一个 Gradle 的服务器,然后把 Android ...

  5. VS2010常用插件

  6. vue-cli 本地数据模拟

    方法一: 使用express搭建静态服务 mock数据写在json文件中,proxyTable 里将接口代理到具体mock数据json文件上.具体方法: 创建 mock 文件夹 build/dev-s ...

  7. bash shell(4):读取文件大小,移动文件,复制文件,字符串转数字

    下面是代码:注意: 1.if [ expression ],表达式两边需要空格 2.a=$[aa],字符串转为int类型 3.赋值的时候不能有空格 #!/bin/shell fn="file ...

  8. 【工具】Windows7搭建FTP服务器

    有时候需要将文件在各台电脑间拷贝,所以想建一个ftp服务器方便些,这里的设置仅为家用设置的记录日志,严谨的生产环境请参考其他文章. 创建一个专用于ftp的用户 开始 > 控制面板 > 用户 ...

  9. Lua语法基础(1)---简介、基本数据类型、表达式

    我觉得我已经陷入了一个坑内.因为,安装了Lua和SublimeText3编辑器之后,怎么使自己编写的lua代码在untiy内运行起来,是个我完全不了解的机制.先放一放吧.首先,来回顾一下Lua的语法基 ...

  10. 【Socket】linux网络扫描程序开发

      1.mystery引入    1)系统入侵步骤:系统发现->漏洞探测->漏洞利用->痕迹清除    2)扫描器分类:主机与网络扫描器:端口服务扫描器:服务漏洞扫描器    3)T ...