专栏首页点云PCLPCL滤波介绍(1)

PCL滤波介绍(1)

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

pcl::ApproximateVoxelGrid< PointT > 类ApproximateVoxelGrid根据给定的点云形成三维体素栅格,并利用所有体素的中心点近似体素中包含的点集,这样完成下采样得到滤波结果,该类比较合适对海量点云数据在处理前进行压缩,提高算法效率

pcl::BilateralFilter< PointT > 类BilateralFilter是对双边滤波算法在点云上的实现,该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现,所以在使用该类时点云的类型必须有强度字段,否则无法进行双边滤波处理,

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

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

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

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

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

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

等等类查询相关官方网站***********88

(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  = 5;
 cloud->height = 1;
 cloud->points.resize (cloud->width * cloud->height);  for (size_t i = 0; i < cloud->points.size (); ++i)   //填充数据  {
   cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f);
   cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
   cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
 } std::cerr << "Cloud before filtering: " << std::endl;   //打印
 for (size_t i = 0; 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 = 0; 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 (0);
}

由于随机生成的点云,所以每次运行结果不一样,但是都会将点云中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>intmain (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 (0);
}

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

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

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

本文分享自微信公众号 - 点云PCL(dianyunPCL),作者:石城大海

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • PCL—低层次视觉—关键点检测(Harris)

      除去NARF这种和特征检测联系比较紧密的方法外,一般来说特征检测都会对曲率变化比较剧烈的点更敏感。Harris算法是图像检测识别算法中非常重要的一个算法,其...

    点云PCL博主
  • PCL点云配准(1)

    在逆向工程,计算机视觉,文物数字化等领域中,由于点云的不完整,旋转错位,平移错位等,使得要得到的完整的点云就需要对局部点云进行配准,为了得到被测物体的完整数据模...

    点云PCL博主
  • 连接两个点云中的字段或数据形成新点云以及Opennni Grabber初识

    (1)学习如何连接两个不同点云为一个点云,进行操作前要确保两个数据集中字段的类型相同和维度相等,同时了解如何连接两个不同点云的字段(例如颜色 法线)这种操作的强...

    点云PCL博主
  • 闯缸鱼:看懂python如何实现整数加和,再决定是否自学编程

    玩鱼缸的新手都知道有一种鱼叫“闯缸鱼”,皮实好养,帮助新手判断鱼缸环境是否准备好。这篇笔记,最初用来解答一个编程新手的疑问,后来我发现,整理一下也可当做有兴趣自...

    刘娟娟PRESSone
  • 用Seurat做RNA Velocity

    If you don't have velocyto's example mouse bone marrow dataset, download with th...

    生信编程日常
  • 【Java】继承、抽象、组合

    Object类包含的主要方法clone方法finalize方法getClass方法notify、notifyAll、wait方法

    用户7886150
  • mybatis中大于等于小于等于的写法

    个人博客:https://suveng.github.io/blog/​​​​​​​

    suveng
  • 【无人驾驶量产得靠128线廉价激光雷达,中国将是最大市场】专访Velodyne自动驾驶VP

    作者:胡祥杰 闻菲 【新智元导读】Velodyne 激光雷达(64线)曾定价7万多美元,被认为是无人驾驶走向商用不得不解决的成本问题。近日,Velodyne...

    新智元
  • 大家的编程故事

    我觉得1万个小时定律真的很对,付出的越多,得到的越多。一定要多敲代码!熟能生巧。不要每次写代码都到网上复制,可以把经典的用例自己总结写个通用的demo,然后去反...

    Crossin先生
  • PHP实现时间日期友好显示实现代码

    系统的友好性在开发过程中是非常重要的,一个系统非常友好不光可以带给用户非常棒的使用体验,而且还可以使系统有这更长的寿命。今天这篇博文主要来展示一个我们如何让日期...

    砸漏

扫码关注云+社区

领取腾讯云代金券