pcl之滤波器(二)

pcl之滤波器(二)_第1张图片

pcl滤波器

pcl一共是有十二个主要模块,详细了解可以查看官网。https://pcl.readthedocs.io/projects/tutorials/en/latest/#basic-usage

今天学习一下pcl的滤波器模块。

滤波器模块,官网一共是提供了6个例程,今天看第三个、第四个。

滤波器移出离群点

激光扫描通常会产生不同点密度的点云数据集。此外,测量误差会导致稀疏的异常值,从而影响结果。这使得局部点云特征(如表面法线或曲率变化)的估计变得复杂,导致错误的值,进而可能导致点云配准失败。其中一些不规则现象可以通过对每个点的邻域进行统计分析来解决,并去除那些不符合特定标准的点。

测试的pcd文件地址
https://raw.github.com/PointCloudLibrary/data/master/tutorials/table_scene_lms400.pcd

#include 
#include 
#include      //声明点类型
#include 

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);
//true:滤波结果取反,被过滤的点
  sor.setNegative (true);
  sor.filter (*cloud_filtered);
  writer.write<pcl::PointXYZ> ("../table_scene_lms400_outliers.pcd", *cloud_filtered, false);

  return (0);
}

代码都有注释,看一下结果吧。

原图
pcl之滤波器(二)_第2张图片

inliers:

pcl之滤波器(二)_第3张图片

outliers:

pcl之滤波器(二)_第4张图片

感觉效果还是比较理想的。

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5 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})

使用参数化模型投影点

这部分主要是学习如何将点投影到参数化模型上(例如,平面,球体等)。参数模型是通过一组系数给出的——在平面的情况下,通过它的方程:ax + by + cz + d = 0。

看一下代码:

#include 
#include 
#include                     //声明点类型
#include              //模型系数头文件
#include           //投影滤波类头文件

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);                 //投影结果存储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;

    system("pause");
    return (0);
}

运行结果如下:
pcl之滤波器(二)_第5张图片

程序的功能也主要就是将三维的点投影到二维xy平面上。

CMakeLists.txt

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(project_inliers)

find_package(PCL 1.2 REQUIRED)

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

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

你可能感兴趣的:(3D,3d)