点云库PCL学习笔记 -- 点云滤波Filtering -- 3. StatisticalOutlierRemoval 统计滤波器

点云库PCL学习笔记 -- 点云滤波Filtering -- 3.StatisticalOutlierRemoval 统计滤波器


StatisticalOutlierRemoval 统计滤波器相关简介

激光扫描通常会产生密度不均匀的点云数据集。另外,测量中的误差会产生稀疏的离群点,使效果更糟。估计局部点云特征(例如采样点出的法向量或者曲率变化率)的运算很复杂,这会导致错误的数值,反过来有可能导致点云的配准等后期处理失败。

以下方法可以解决其中部分问题:对每个点的邻域进行一个统计分析,并修剪掉那些不符合一定标准的点。我们的稀疏离群点一处方法基于输入数据中对点到临近点的距离分布的计算。对每个点,我们计算它到它的所有临近点的平均距离。假设得到的结果是一个高斯分布,其形状由均值和标准差决定,平均距离在标准范围(由全局平均值和方差定义)之外的点,可以被定义为离群点并可从数据集中去除掉。

  • 下图展示了稀疏离群点分析和移除效果
  • 左1图为原始数据集,左2图为处理结果;
  • 右图展示了处理签和处理后,一个点邻域范围内的k近邻邻域平均距离。

在这里插入图片描述


1. StatisticalOutlierRemoval 统计滤波器代码

StatisticalOutlierRemoval 统计滤波器代码statistical_removal.cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>	//统计滤波类头文件

int
main (int argc, char** argv)
{
  //定义并实例化一个PointCloud指针对象,并用读取文件数据点集赋值给它
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);

  //点云读取对象
  pcl::PCDReader reader;
  
  reader.read<pcl::PointXYZ> ("table_scene_lms400.pcd", *cloud);	//读取点云文件中的数据到 cloud 对象,table_scene_lms400.pcd 文件与该cpp文件在同一级目录下

  //打印点云数据的相关信息
  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;

  //创建 StatisticalOutlierRemoval 统计滤波器
  //对每个点分析的临近点的个数设置为50,并将标准差的倍数设置为 1.0 这意味着如果一个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
  pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;	//创建 StatisticalOutlierRemoval 滤波对象
  sor.setInputCloud (cloud);							//设置输入点云
  sor.setMeanK (50);									//设置在进行统计时考虑查询点临近点数,对每个点分析的临近点的个数设置为50
  sor.setStddevMulThresh (1.0);							//设置判断是否为离群点的阈值,将标准差的倍数设置为 1.0
  sor.filter (*cloud_filtered);							//执行完滤波处理保存数据点云到 cloud_filtered

  //打印滤波完后的点云数据信息
  std::cerr << "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  //将滤波后,保存的点云写入 table_scene_lms400_inliers.pcd 文件
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("table_scene_lms400_inliers.pcd", *cloud_filtered, false);

  //将滤波后,被过滤的点云写入 table_scene_lms400_outliers.pcd 文件
  sor.setNegative (true);			// true:滤波结果取反,被过滤掉的点云数据
  sor.filter (*cloud_filtered);
  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);

  return (0);
}

2. 编译文件

设置编译文件CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(statistical_removal)
find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (statistical_removal statistical_removal.cpp)
target_link_libraries (statistical_removal ${PCL_LIBRARIES})

编译
mkdir build
cd build/
cmake ..
make

3. 测试

执行程序

cd ..
./build/statistical_removal

结果如下:

  • 未开始滤波时,工程文件的目录如下所示。
    目录中的table_scene_lms400.pcd原始文件与statistical_removal.cpp文件在同一级目录下。
    在这里插入图片描述
    使用pcl_viewer table_scene_lms400.pcd查看table_scene_lms400.pcd文件,如下
    可以很清楚的看到,该点云文件的离群点数量相对比较多。
    在这里插入图片描述

  • 开始执行程序后
    相关的输出信息
    在这里插入图片描述
    文件目录变化如下所示,程序运行完成后会生成一个table_scene_lms400_inliers.pcd保存的点云文件和一个table_scene_lms400_outliers.pcd保存的点云文件,这两个文件为通过StatisticalOutlierRemoval 统计滤波器统计滤波后的文件。
    在这里插入图片描述

  • 使用pcl_viewer table_scene_lms400_inliers.pcd查看table_scene_lms400_inliers.pcd文件,如下所示:
    可以很清楚的看到,该点云文件相比之前的原始数据文件离群点少了很多。
    在这里插入图片描述

  • 使用pcl_viewer table_scene_lms400_outliers.pcd查看table_scene_lms400_outliers.pcd文件,如下所示:
    该图为由 StatisticalOutlierRemoval 统计滤波器过滤筛选掉的离群点。
    在这里插入图片描述
    两张图的相对比较如下。
    在这里插入图片描述


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值