1.PCL滤波概述
在获取点云数据时 ,由于设备精度,操作者经验环境因素带来的影响,以及电磁波的衍射特性,被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中讲不可避免的出现一些噪声。在点云处理流程中滤波处理作为预处理的第一步,对后续的影响比较大,只有在滤波预处理中将噪声点 ,离群点,孔洞,数据压缩等按照后续处理定制,才能够更好的进行配准,特征提取,曲面重建,可视化等后续应用处理,PCL中点云滤波模块提供了很多灵活实用的滤波处理算法,例如:PassThrough直通滤波、VoxelGrid过滤、StatisticalOutlierRemoval过滤、点云投影、提取索引等;下面将对几种常见滤波进行介绍。
2.PCL中点云滤波的方案
PCL中总结了几种需要进行点云滤波处理情况,这几种情况分别如下:
(1) 点云数据密度不规则需要平滑
(2) 因为遮挡等问题造成离群点需要去除
(3) 大量数据需要下采样
(4) 噪声数据需要去除
对应的方案如下:
(1)按照给定的规则限制过滤去除点
(2) 通过常用滤波算法修改点的部分属性
(3)对数据进行下采样
3.常见滤波概述
直通滤波:快速过滤掉用户自定义区间范围内的点云,效果最为明显并且也最容易理解。
体素滤波:在分割、配准前,如果点云数量太多会影响后续时间。此时,需要对点云进行下采样处理,体素滤波为采用体素网格方法采样,减少点云数量。
统计滤波:统计滤波往往去除离群点,利用统计分析技术删除噪声异常值等。
投影点云:将点投影到一个参数化模型上(平面或者球体等)。
提取索引:基于某一分割算法提取点云中的子集。
4.几种常见滤波使用实例
对于下面各种滤波的使用并没有只用文字来阐述,而是主要在代码的注释中,我认为这样会便于理解。
4.1.直通滤波
直通滤波通俗来讲就是设置一个范围,经该范围内或者该范围外的点云数据剔除,是一种简单暴力但效果明显的方式。
代码:
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
int main (int argc, char** argv)
{
//点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
//处理后点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_handle(new pcl::PointCloud<pcl::PointXYZ>);
//处理后点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_handle2(new pcl::PointCloud<pcl::PointXYZ>);
//从点云文件中读取点云数据
pcl::io::loadPCDFile("d:/2.pcd", *cloud);
//目的:通过直通滤波器将某个方向范围的点云数据过滤掉
// 设置滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass;
//z坐标轴
pass.setInputCloud (cloud); //设置输入点云
pass.setFilterFieldName ("x"); //设置过滤的坐标轴方向
pass.setFilterLimits (-90, 90); //设置在过滤掉的坐标范围
pass.setFilterLimitsNegative (false); //设置过滤范围内还是范围外,当为false为范围外
pass.filter (*cloud_handle); //过滤器过滤,过滤后点云数据保存在cloud_handle中
// 设置滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass2;
//z坐标轴
pass.setInputCloud (cloud_handle); //设置输入点云
pass.setFilterFieldName ("y"); //设置过滤的坐标轴方向
pass.setFilterLimits (-86, 50); //设置在过滤掉的坐标范围
pass.setFilterLimitsNegative (false); //设置过滤范围内还是范围外,当为false为范围外
pass.filter (*cloud_handle2); //过滤器过滤,过滤后点云数据保存在cloud_handle中
//处理后点云显示
pcl::visualization::CloudViewer viewer("PCL滤波");
viewer.showCloud(cloud_handle2);
while (!viewer.wasStopped()){