PCL从0到1|点云滤波之直通滤波与体素法滤波

3D视觉工坊的第51篇文章

今天呢,想和大家聊一聊点云滤波处理的相关模块。

我对点云模块了解得也不算深入,此处单纯地想和大家分享一下这几天我所学习到的点云滤波知识,如有不到之处,还请后台留言多多指正。

在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,点云数据中将不可避免地出现一些噪声点。这便需要我们队点云进行后处理。

在点云的处理流程中,滤波处理作为预处理的第一步,往往对后续处理管道影响最大,只有在滤波预处理中将噪声点、离群点、空洞等按照后续处理定制,才能更好地进行配准、特征提取、曲面重建、可视化等。

PCL中的点云处理模块提供了很多灵活实用的滤波处理算法,例如双边滤波、高斯滤波、条件滤波、直通滤波、基于随机采样一致性滤波等。

PCL中总结了几种需要进行点云滤波处理的情况,这几种情况如下:

(1)点云数据密度不规则需要平滑; (2)因为遮挡等问题造成离群点需要去除; (3)大量数据需要进行下采样; (4)噪音数据需要去除。

对应的方法主要如下:

(a)按具体给定的规则限制过滤去除点。 (b)通过常用滤波算法修改点的部分属性。 (c)对数据进行下采样。

PCL中对常规的滤波手段进行了良好地封装,主要的滤波器有直通滤波、体素法滤波、统计滤波、条件滤波等。组合使用完成任务,效果更佳。

1、如果是线结构光的采集方式得到的点云,则沿z向的分布较广,但沿x、y方向的分布则处于有限的范围内。此时,可采用直通滤波,确定x或者y方向的范围,快速裁剪离群点。

2、如果使用高分辨率相机等设备对点云进行采集,则点云往往较为密集。过多的点云数据对后续的分割工作带来困难。体素法滤波可以达到下采样的同时不破坏点云本身几何结构的功能。

3、统计滤波器用于去除明显的离群点(离群点往往由噪声引入)。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除3∑之外的点。

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

接下来,以demo的形式简单介绍一下PCL中关于直通滤波和体素法滤波的功能及函数使用方法。

直通滤波

直通滤波功能:指定字段,指定坐标范围进行剪裁,可以选择保留范围内的点或者范围外的点。

//相关的头文件声明

#include <iostream> //标准C++库中输入输出类相关头文件

#include <pcl/io/pcd_io.h> //pcd读写类相关头文件

#include "pcl/point_cloud.h"

#include <pcl/point_types.h> //PCL中支持的点类型头文件

#include<pcl/common/common.h>

#include <pcl/filters/passthrough.h>

int main()

{

//创建一个PointCloud<PointXYZ> boost 共享指针并进行实例化

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

//滤波后的点云

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

//pcd文件路径

std::string pcd_in = "../rops_cloud.pcd";

std::string pcd_out = "../rops_cloud_passthroughed.pcd";

if (pcl::io::loadPCDFile<pcl::PointXYZ>(pcd_in,*cloud)==-1)

    //打开点云文件

{

PCL_ERROR("Couldn't read file test_pcd.pcd\n");

return(-1);

}

pcl::PointXYZ minPt, maxPt;

pcl::getMinMax3D(*cloud,minPt,maxPt);

// 创建滤波器对象

pcl::PassThrough<pcl::PointXYZ> pass; //设置滤波器对象

pass.setInputCloud(cloud);//设置输入点云

pass.setFilterFieldName("z"); //设置过滤时所需要的点云类型的z字段

pass.setFilterLimits(minPt.z+0.2, maxPt.z - 0.1); //设置在过滤字段上的范围

pass.setFilterLimitsNegative(false); //设置保留范围内的还是过滤掉范围内的

pass.filter(*cloud_filtered); //执行滤波

//将数据存储到磁盘

pcl::io::savePCDFileASCII(pcd_out,*cloud_filtered);

return (0);

}

 直通滤波的演示效果图,如下图所示。

PCL从0到1|点云滤波之直通滤波与体素法滤波以上的相关代码与CmakeList.txt文件可以在公众号「3D视觉工坊」后台回复「直通滤波」即可获得下载链接。

体素法滤波

体素法滤波,即减少点的数量,减少点云数据,并同时保持点云的形状特征,在提高配准、曲面重建、形状识别等算法速度中非常实用。 PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格(可把体素栅格想象为微小的空间三维立方体的集合),然后在每个体素(即三维立方体)内,用体素中所有点的重心来近似显示体素中其他点,这样该体素内所有点就用一个重心点最终表示,对于所有体素处理后得到过滤后的点云。 优缺点:这种方法比用体素中心来逼近的方法更慢,但它对于采样点对应曲面的表示更为准确。

#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_scene_lms400.pcd", *cloud); // 读取点云文件中的数据到cloud对象

  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height  << " data points (" << pcl::getFieldsList(*cloud) << ")." <<std::endl;

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 (0);

}

以上代码运行结果如下图1. 将点云结果放在CloudCampare中对比显示如图2.

PCL从0到1|点云滤波之直通滤波与体素法滤波

PCL从0到1|点云滤波之直通滤波与体素法滤波

对于测试数据与代码已经放在百度云网盘,在微信公众号「3D视觉工坊」后台回复「体素法滤波」,即可获得下载链接。

由以上可以看出,体素法处理前后,点的密度大小与整齐程度不同,虽然处理后数据量大大减少,但很明显其所含有的形状特征与空间结构信息与原始点云差不多。

接下来的文章,还会涉及点云滤波模块的其他方法,感兴趣的小伙伴可以持续关注,也可以加入「3D视觉工坊」知识星球持续学习。

PCL从0到1|点云滤波之直通滤波与体素法滤波

参考:

https://www.cnblogs.com/zhaobinyouth/p/6196358.html

参考书籍:

郭浩主编的《点云库PCL从入门到精通》

上述内容,如有侵犯版权,请联系作者,会自行删文。

荐读

回复关键词——1,前往知识星球

PCL从0到1|点云滤波之直通滤波与体素法滤波