PCL滤波介绍(2)

简介: (1)使用statisticalOutlierRemoval滤波器移除离群点  使用统计分析技术,从一个点云数据中集中移除测量噪声点(也就是离群点)比如:激光扫描通常会产生密度不均匀的点云数据集,另外测量中的误差也会产生稀疏的离群点,使效果不好,估计局部点云特征(例如采样点处法向量或曲率变化率)的运算复杂,这会导致错误的数值,反过来就会导致点云配准等后期的处理失败。

(1)使用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)
{
  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);

  std::cerr << "Cloud before filtering: " << std::endl;
  std::cerr << *cloud << std::endl;

  // 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1  这意味着如果一
   //个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
  pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;   //创建滤波器对象
  sor.setInputCloud (cloud);                           //设置待滤波的点云
  sor.setMeanK (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);
  writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);

  return (0);
}

运行结果为:

( 2)使用参数化模型投影点云

   如何将点投影到一个参数化模型上(平面或者球体等),参数化模型通过一组参数来设定,对于平面来说使用其等式形式.在PCL中有特意存储常见模型系数的数据结构

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>             //模型系数头文件
#include <pcl/filters/project_inliers.h>          //投影滤波类头文件

int
 main (int argc, char** argv)
{
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (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 projection: " << 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;

  // 填充ModelCoefficients的值,使用ax+by+cz+d=0平面模型,其中 a=b=d=0,c=1 也就是X——Y平面
  //定义模型系数对象,并填充对应的数据
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  coefficients->values.resize (4);
  coefficients->values[0] = coefficients->values[1] = 0;
  coefficients->values[2] = 1.0;
  coefficients->values[3] = 0;

  // 创建ProjectInliers对象,使用ModelCoefficients作为投影对象的模型参数
  pcl::ProjectInliers<pcl::PointXYZ> proj;     //创建投影滤波对象
  proj.setModelType (pcl::SACMODEL_PLANE);      //设置对象对应的投影模型
  proj.setInputCloud (cloud);                   //设置输入点云
  proj.setModelCoefficients (coefficients);       //设置模型对应的系数
  proj.filter (*cloud_projected);                 //投影结果存储

  std::cerr << "Cloud after projection: " << std::endl;
  for (size_t i = 0; i < cloud_projected->points.size (); ++i)
    std::cerr << "    " << cloud_projected->points[i].x << " " 
                        << cloud_projected->points[i].y << " " 
                        << cloud_projected->points[i].z << std::endl;

  return (0);
}

编译运行的结果如下

实验结果可以看出投影前的Z轴都不为0 ,都是随机产生的值,投影之后,打印的结果表明,xy的值都没有改变,z都变为0

所以该投影滤波类就是输入点云和投影模型,输出为投影到模型上之后的点云。

 

 

 

未完待续**************************88888

相关文章
|
C++ 计算机视觉
OpenCV-巴特沃斯低通&高通滤波器(C++)
OpenCV-巴特沃斯低通&高通滤波器(C++)
350 0
|
算法 数据处理
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
1276 0
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
|
3月前
|
C++
C++ PCL 求两个平面的交线
C++ PCL 求两个平面的交线
47 0
|
6月前
|
存储 编解码 资源调度
【OpenCV】—线性滤波:方框滤波、均值滤波、高斯滤波
【OpenCV】—线性滤波:方框滤波、均值滤波、高斯滤波
338 2
|
计算机视觉
opencv 之 各种滤波总结
opencv 之 各种滤波总结
|
存储 算法
|
传感器 编解码 索引
|
数据可视化 算法
|
编解码 数据可视化 数据挖掘
PCL特征点与配准(1)
关于输入一个具体的物体的点云,从场景中找出与该物体点云相匹配的,这种方法可以用来抓取指定的物体等等,具体的代码的解释如下,需要用到的一些基础的知识,在之前的博客中都有提及,其中用到的一些方法可以翻阅前面的博客,当然有问题可以关注公众号,与众多爱好者一起交流 具体的代码实现 #include #include //点云类型头文件 #include //对应表示两个实体之间的匹配(例如,点,描述符等)。
2463 0
|
存储 算法 数据可视化
PCL点云配准(1)
在逆向工程,计算机视觉,文物数字化等领域中,由于点云的不完整,旋转错位,平移错位等,使得要得到的完整的点云就需要对局部点云进行配准,为了得到被测物体的完整数据模型,需要确定一个合适的坐标系,将从各个视角得到的点集合并到统一的坐标系下形成一个完整的点云,然后就可以方便进行可视化的操作,这就是点云数据的配准。
2579 0