PCL_几种点云滤波方法

PCL_几种点云滤波方法

杉木~ 2020-01-15 20:11:29  1608  收藏 2
分类专栏: PCL学习
版权

PCL学习
专栏收录该内容
22 篇文章5 订阅
订阅专栏
通常点云数据很大,同时带有噪声和离群点,在点云分析之前需要先进行滤波处理,学习郭浩老师的点云处理,总结几种滤波方法。
1. 直通滤波器

// 创建滤波器对象
  pcl::PassThrough pass;
  pass.setInputCloud (cloud);
  pass.setFilterFieldName ("z");
  pass.setFilterLimits (0.0, 1.0);
  //pass.setFilterLimitsNegative (true);
  pass.filter (*cloud_filtered);
1
2
3
4
5
6
7
2. VoxelGrid滤波器
创建三维体素栅格,将体素栅格内所有点的重心代替体素中其他点,实现下采样。

// 创建滤波器对象
    pcl::VoxelGrid sor;
    sor.setInputCloud(cloud);
    sor.setLeafSize(0.01f, 0.01f, 0.01f);
    sor.filter(*cloud_filtered);
1
2
3
4
5
3.StatisticalOutlireRemoval滤波器
对每一个点的近邻进行一个统计分析,计算点到近邻点的距离,计算所有近邻点的平均距离,平均距离在标准范围之外的点被视为离群点。

// 创建滤波器对象
  pcl::StatisticalOutlierRemoval sor;
  sor.setInputCloud (cloud);
  sor.setMeanK (50);
  sor.setStddevMulThresh (1.0);
  sor.filter (*cloud_filtered);
1
2
3
4
5
6
4. 使用参数化模型投影点云
基于对模型的结构和尺寸等信息,选择特殊模型,如:球等,设置参数进行滤波。
(1)填充ModelCoefficients的值,该例中使用X-Y平面

//创建一个系数为(0,0,1,0)的平面
    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;
1
2
3
4
5
6
(2)创建ProjectInliers对象,使用ModelCoefficients作为投影对象的模型参数

//创建滤波器对象
    pcl::ProjectInliersproj;
    proj.setModelType(pcl::SACMODEL_PLANE);
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*cloud_projected);
1
2
3
4
5
6
5. ExtractIndices滤波器
基于某一分割算法提取点云的一个子集
(1)使用VoxelGrid滤波器对数据下采样,加快处理速度

// 创建滤波器对象:使用叶大小为1cm的下采样
    pcl::VoxelGrid sor;
    sor.setInputCloud(cloud_blob);
    sor.setLeafSize(0.01f, 0.01f, 0.01f);
    sor.filter(*cloud_filtered_blob);
1
2
3
4
5
(2)参数化分割
(3)设置extraction filter实际参数

    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices());
    // 创建分割对象
    pcl::SACSegmentation seg;
    // 可选
    seg.setOptimizeCoefficients(true);
    // 必选
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setMaxIterations(1000);
    seg.setDistanceThreshold(0.01);
    // 创建滤波器对象
    pcl::ExtractIndices extract;
    int i = 0, nr_points = (int)cloud_filtered->points.size();
    // 当还有30%原始点云数据时
    while (cloud_filtered->points.size() > 0.3 * nr_points)
    {
        // 从余下的点云中分割最大平面组成部分
        seg.setInputCloud(cloud_filtered);
        seg.segment(*inliers, *coefficients);
        if (inliers->indices.size() == 0)
        {
            std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
            break;
        }
        // 分离内层
        extract.setInputCloud(cloud_filtered);
        extract.setIndices(inliers);
        extract.setNegative(false);
        extract.filter(*cloud_p);
        std::cerr << "PointCloud representing the planar component: " << cloud_p->width * cloud_p->height << " data points." << std::endl;
        std::stringstream ss;
        ss << "table_scene_lms400_plane_" << i << ".pcd";
        writer.write(ss.str(), *cloud_p, false);
        // 创建滤波器对象
        extract.setNegative(true);
        extract.filter(*cloud_f);
        cloud_filtered.swap(cloud_f);
        i++;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
需要将sensor_msgs::PointCloud2::Ptr改为pcl::PCLPointCloud2::Ptr;pcl::fromROSMsg()改为pcl::fromPCLPointCloud2();

6. ConditionalRemoval或RadiusOutlierRemoval类
ConditionalRemoval滤波器可以删除设定的一个或多个条件指标的所有数据点;
(1)创建条件限定对象;
(2)为限定对象添加比较算子;
(3)创建滤波器并用条件定义对象初始化;

// 创建环境
pcl::ConditionAnd::Ptr range_cond(new
            pcl::ConditionAnd());
range_cond->addComparison(pcl::FieldComparison::ConstPtr(new
            pcl::FieldComparison("z", pcl::ComparisonOps::GT, 0.0)));
range_cond->addComparison(pcl::FieldComparison::ConstPtr(new
            pcl::FieldComparison("z", pcl::ComparisonOps::LT, 0.8)));
// 创建滤波器
pcl::ConditionalRemoval condrem(range_cond);
condrem.setInputCloud(cloud);
condrem.setKeepOrganized(true);
// 应用滤波
condrem.filter(*cloud_filtered);
1
2
3
4
5
6
7
8
9
10
11
12
13
RadiusOutlinerRemoval滤波器删除搜索半径内不满足设定的近邻点数,可用于移除离群点。
(1)创建滤波器;
(2)设置搜索半径;
(3)设置查询点的近邻点数;
(4)执行条件滤波。

pcl::RadiusOutlierRemoval outrem;
// 创建滤波器
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.8);
outrem.setMinNeighborsInRadius(2);
// 应用滤波器
outrem.filter(*cloud_filtered);
1
2
3
4
5
6
7
7. CropHull滤波器
获取2D封闭多边形内部或者外部的点云
(1)设置2D封闭多边形顶点;
(2)使用ConvexHull类构造2D凸包;
(3)创建Crophull对象,滤波获取凸包范围内的点云。

pcl::PointCloud::Ptr boundingbox_ptr(new pcl::PointCloud);
    boundingbox_ptr->push_back(pcl::PointXYZ(0.1, 0.1, 0));
    boundingbox_ptr->push_back(pcl::PointXYZ(0.1, -0.1, 0));
    boundingbox_ptr->push_back(pcl::PointXYZ(-0.1, 0.1, 0));
    boundingbox_ptr->push_back(pcl::PointXYZ(-0.1, -0.1, 0));
    boundingbox_ptr->push_back(pcl::PointXYZ(0.15, 0.1, 0));

    pcl::ConvexHull hull;
    hull.setInputCloud(boundingbox_ptr);
    hull.setDimension(2);
    std::vector polygons;
    pcl::PointCloud::Ptr surface_hull(new pcl::PointCloud);
    hull.reconstruct(*surface_hull, polygons);

    pcl::PointCloud::Ptr objects(new pcl::PointCloud);
    pcl::CropHull bb_filter;
    bb_filter.setDim(2);
    bb_filter.setInputCloud(cloud);
    bb_filter.setHullIndices(polygons);
    bb_filter.setHullCloud(surface_hull);
    bb_filter.filter(*objects);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

杉木~
关注

————————————————
版权声明:本文为CSDN博主「杉木~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhan_zhan1/article/details/103991733

你可能感兴趣的:(WPF,C#,PLC,自动驾驶,机器学习,人工智能)