12

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

 3 years ago
source link: https://mp.weixin.qq.com/s/bnfrVK69kqFj1xXA2-GhGQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

640?wx_fmt=gif
以上的相关代码与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.

640

640?wx_fmt=gif

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

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

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

640

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

参考书籍:

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

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

PCL-1.8.1从源码搭建开发环境四(VTK的编译)

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

640?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK