zoukankan      html  css  js  c++  java
  • PCL点云滤波

    点云处理中滤波目的。滤波处理作为点云处理的第一步,对后续处理有很重要。只有在滤波处理流程中将噪声点、离群点、空洞、数据压缩等按照后续处理定制,才能更好地进行配准、特征提取、曲面重建、可视化等后续应用处理。点云数据集中每一个点表达一定的信息量,某个区域点越密集有用的信息量越大。孤立的离群点信息量较小,其表达的信息量可以忽略不计。

    滤波器介绍
    直通滤波器:对于在空间分布有一定空间特征的点云数据,比如使用线结构光扫描的方式采集点云,沿z向分布较广,但x,y向的分布处于有限范围内。此时可使用直通滤波器,确定点云在x或y方向上的范围,可较快剪除离群点,达到第一步粗处理的目的。

    体素滤波器:体素的概念类似于像素,使用AABB包围盒将点云数据体素化,一般体素越密集的地方信息越多,噪音点及离群点可通过体素网格去除。另一方面如果使用高分辨率相机等设备对点云进行采集,往往点云会较为密集。过多的点云数量会对后续分割工作带来困难。体素滤波器可以达到向下采样同时不破坏点云本身几何结构的功能。

    统计滤波器:考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除3∑之外的点。

    条件滤波:条件滤波器通过设定滤波条件进行滤波,有点分段函数的味道,当点云在一定范围则留下,不在则舍弃。

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

     1 #include<iostream>
     2 #include<pcl/point_types.h>
     3 #include<pcl/filters/passthrough.h>  //直通滤波器头文件
     4 #include<pcl/filters/voxel_grid.h>  //体素滤波器头文件
     5 #include<pcl/filters/statistical_outlier_removal.h>   //统计滤波器头文件
     6 #include <pcl/filters/conditional_removal.h>    //条件滤波器头文件
     7 #include <pcl/filters/radius_outlier_removal.h>   //半径滤波器头文件
     8  
     9  
    10 int main(int argc, char** argv)
    11 {
    12   
    13   //读取文件
    14   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    15   if(pcl::io::loadPCDFile("PointCloud.pcd",cloud)==-1)
    16   {
    17     PCL_ERROR("Couldn't read file test_pcd.pcd
    ");
    18     return(-1);
    19   }
    20   //************************滤波****************************
    21   //【1】直通滤波
    22   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>);//
    23   pcl::PassThrough<pcl::PointXYZ> passthrough;
    24   passthrough.setInputCloud(cloud);//输入点云
    25   passthrough.setFilterFieldName("z");//对z轴进行操作
    26   passthrough.setFilterLimits(0.0, 400.0);//设置直通滤波器操作范围
    27   //passthrough.setFilterLimitsNegative(true);//true表示保留范围内,false表示保留范围外
    28   passthrough.filter(*cloud_after_PassThrough);//执行滤波,过滤结果保存在 cloud_after_PassThrough
    29  
    30   //【2】体素滤波器实现下采样
    31   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_voxelgrid(new pcl::PointCloud<pcl::PointXYZ>);//
    32   pcl::VoxelGrid<pcl::PointXYZ> voxelgrid; 
    33   voxelgrid.setInputCloud(cloud);//输入点云数据
    34   voxelgrid.setLeafSize(0.05f, 0.05f, 0.05f);//创建的体素大小为5cm立方体
    35   voxelgrid.filter(*cloud_after_voxelgrid);
    36   
    37   //【3】统计滤波器滤波
    38   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_StatisticalRemoval(new pcl::PointCloud<pcl::PointXYZ>);//
    39   pcl::StatisticalOutlierRemoval<pcl::PointXYZ> Statistical;
    40   Statistical.setInputCloud(cloud);
    41   Statistical.setMeanK(50);//取平均值的临近点数
    42   Statistical.setStddevMulThresh(5);//临近点数数目少于多少时会被舍弃
    43   Statistical.filter(*cloud_after_StatisticalRemoval);
    44   
    45   //【4】条件滤波器
    46   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Condition(new pcl::PointCloud<pcl::PointXYZ>);
    47   pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_condition(new pcl::ConditionAnd<pcl::PointXYZ>());
    48   range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
    49     pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::GT, 0.0)));  //GT表示大于等于
    50   range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
    51     pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::LT, 0.8)));  //LT表示小于等于
    52   pcl::ConditionalRemoval<pcl::PointXYZ> condition;
    53   condition.setCondition(range_condition);
    54   condition.setInputCloud(cloud);                   //输入点云
    55   condition.setKeepOrganized(true);
    56   condition.filter(*cloud_after_Condition);
    57   
    58   //【5】半径滤波器
    59   pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
    60   pcl::RadiusOutlierRemoval<pcl::PointXYZ> radiusoutlier;  //创建滤波器
    61   radiusoutlier.setInputCloud(cloud);    //设置输入点云
    62   radiusoutlier.setRadiusSearch(100);     //设置半径为100的范围内找临近点
    63   radiusoutlier.setMinNeighborsInRadius(2); //设置查询点的邻域点集数小于2的删除                            
    64   radiusoutlier.filter(*cloud_after_Radius);
    65   
    66  
    67  
    68 }
  • 相关阅读:
    一点一点学习GIt
    17-ajax向后端提交POST请求
    16-djongo中间件学习
    ES6快速入门
    15 Django组件——中间件
    导入Scrapy 项目报错:no module named scrapy
    slf4j + logback 输出日志:mybatis sql语句
    java实现链表
    Log4j2.xml的日志设置
    java多线程之生产者消费者经典问题
  • 原文地址:https://www.cnblogs.com/hsy1941/p/11947228.html
Copyright © 2011-2022 走看看