PCL使用StaticalOutlierRemoval(统计分析滤波)进行滤波

原理:对每个点找其到其K近邻的的点的距离的平均值d,所有的点的平均值应该呈现高斯分布(正态分布),其形状由均值和标准差决定,平均距离d在标准范围内 (由全局距离平均值<所有的d相加的和>和方差定义)之外的点,可以被定义为离群点并剔除。

代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.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>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_out(new pcl::PointCloud<pcl::PointXYZ>);//保存滤除掉的点
  // 填入点云数据
  pcl::PCDReader reader;
  // 把路径改为自己存放文件的路径
  reader.read<pcl::PointXYZ> ("table_scene_lms400.pcd", *cloud);
  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;//重载了<<运算符.重载为全局的,但是为啥可以访问PointCloud类的成员变量呢?
  // 创建滤波器对象
  pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
  sor.setInputCloud (cloud);
  sor.setMeanK (100);//寻找每个点的50个最近邻点
  sor.setStddevMulThresh (1.0);//一个点的最近邻距离超过全局平均距离的一个标准差以上,就会舍弃
  sor.filter (*cloud_filtered);
  std::cerr << "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("table_scene_lms400_inliers.pcd", *cloud_filtered, false);
  sor.setNegative (true);//获取刚才的离群点
  sor.filter (*cloud_filtered_out);
  std::cerr << "Cloud_outside after filtering: " << std::endl;
  std::cerr << *cloud_filtered_out << std::endl;
  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered_out, false);

  pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
  viewer->initCameraParameters();

  int v1(0);
  viewer->createViewPort(0,0,0.33,1,v1);
  viewer->setBackgroundColor(0,0,0,v1);
  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloud,255,255,255);
  viewer->addPointCloud<pcl::PointXYZ>(cloud,single_color1,"cloud",v1);

  int v2(0);
  viewer->createViewPort(0.33,0,0.66,1,v2);
  viewer->setBackgroundColor(128,0,0,v2);
  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color2(cloud_filtered,0,255,0);
  viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered,single_color2,"cloud_filtered",v2);

  int v3(0);
  viewer->createViewPort(0.66,0,1,1,v3);
  viewer->setBackgroundColor(128,128,128,v3);
  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color3(cloud_filtered_out,0,0,255);
  viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered_out,single_color3,"cloud_filtered_out",v3);

  viewer->addCoordinateSystem();

  viewer->spin();
  return (0);
}

结果:依次为原数据、滤波之后的数据、滤掉的数据

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tech沉思录

点赞加投币,感谢您的资瓷~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值