点云数据滤波处理(PCL实现)

引:

​​​​​​点云数据滤波处理(PCL实现) - 简书

2020.01.03 14:29:02字数 942阅读 5,412

点云数据滤波处理(PCL实现)

1.滤波器介绍

点云目标识别的流程:数据采集->滤波->点云分割->点云识别,数据采集可以通过RGBD相机或者激光雷达等设备采集。由于采集设备精度,环境因素,光照因素,物体表面性质等影响,会导致点云数据不可避免的出现噪音。滤波过程就是为了解决点云数据密度不规则不平滑,离群点,大数据降采样,空洞,噪声数据等问题。
点云数据滤波处理(PCL实现)

主要的滤波器

直通滤波器,体素滤波器,统计滤波器,半径滤波器,双边滤波器,中值滤波,卷积滤波,高斯滤波,条件滤波

双边滤波器:
直通滤波器:就是设置一个x、y、z方向的一个取值范围,以过滤掉明显不在测试距离范围的点云;使用Intel RealSense或者激光雷达采集的数据,可设置一个x,y,z合理的范围,过滤掉我们不需要的点云。

体素滤波器:如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。过多的点云数量会对后续分割工作带来困难。体素格滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。点云几何结构不仅是宏观的几何外形,也包括其微观的排列方式,比如横向相似的尺寸,纵向相同的距离。

统计滤波器:用于去除明显离群点(离群点往往由测量噪声引入)。其特征是在空间中分布稀疏,可以理解为:每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。

半径滤波:半径滤波器与统计滤波器相比更加简单粗暴。以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是圆的半径和圆内点的数目都需要人工指定。

2. PCL滤波器源码

2.1 直通滤波器

直通滤波器代码演示:首先从文件中加载一个自行车模型,可视化后

1578042283(1).jpg

#include "stdafx.h"

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/pcd_io.h> 
#include <pcl/io/ply_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/bilateral.h>
#include <pcl/filters/fast_bilateral.h>
#include <pcl/filters/fast_bilateral_omp.h>
#include <pcl/filters/radius_outlier_removal.h>

using namespace std;
int main()
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

    if (pcl::io::loadPLYFile<pcl::PointXYZ>("Bicycle.ply", *cloud) == -1) //* load the file 
    {
        PCL_ERROR("Couldn't read file test_pcd.pcd \n");
        system("PAUSE");
        return (-1);
    }

    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0.0, 2.4); //设置Z轴范围为0.0到2.4m
    pass.filter(*cloud_filtered);
    //显示滤波前的点云 
    pcl::visualization::PCLVisualizer viewer("passthrough viewer");
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud_filtered, "z");//按照z字段进行渲染
    viewer.addPointCloud(cloud_filtered, fildColor, "origin cloud");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "origin clouds");
    
    while (!viewer.wasStopped()) {
        viewer.spinOnce();
    }
    return (0);
}

通过设置调用pass.setFilterLimits(0.0, 2.4); 设置Z轴范围为0.0到2.4m,将大于2.4m的全部过滤掉。效果如下(自行车后面的墙体被裁剪掉):

1578042462.jpg

2.2 体素滤波器

体素滤波器方法这边只粘贴关键代码,其他代码上面已经提供

pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setLeafSize(0.01f, 0.01f, 0.01f);//设置体素大小,米为单位
sor.filter(*cloud_filtered);

1578054606(1).jpg

2.3 统计滤波器

pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setMeanK(5);
sor.setStddevMulThresh(1.0);
sor.filter(*cloud_filtered);

滤波前点云

滤波后点云

滤波后的点云明显去除了飞点

2.4 半径滤波

pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
outrem.setInputCloud(cloud);
outrem.setRadiusSearch(0.01);
outrem.setMinNeighborsInRadius(5);
outrem.filter(*cloud_filtered);

1578055839(1).jpg

会将PCL所有滤波器全部演示一次,未完待续...

参考:

猜你喜欢

转载自blog.csdn.net/u014090257/article/details/121167933
今日推荐