五种常用点云滤波

本文主要介绍五中点云滤波方法:直通滤波器、体素滤波器、统计滤波器、条件滤波器、半径滤波器。

噪声点与离群点。在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,以及电磁波衍射特性、被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免地出现一些噪声点,属于随机误差。除此之外,由于受到外界干扰如视线遮挡,障碍物等因素的影响,点云数据中往往存在着一些距离主题点云较远的离散点,即离群点。

《五种常用点云滤波》离群点

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

滤波器介绍

直通滤波器:对于在空间分布有一定空间特征的点云数据,比如使用线结构光扫描的方式采集点云,沿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. int main(int argc, char** argv)
  9. {
  10. ///////****************************************************////////////////////
  11. /*创建点云数据集。*/
  12. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  13. cloud->width = 500;
  14. cloud->height = 1;
  15. cloud->points.resize(cloud->width*cloud->height);
  16. std:: cout << "创建原始点云数据" << std:: endl;
  17. for ( size_t i = 0; i < cloud->points.size(); ++i)
  18. {
  19. cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
  20. cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
  21. cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
  22. }
  23. for ( size_t i = 0; i < cloud->points.size(); i++)
  24. {
  25. std:: cerr << " " << cloud->points[i].x << " "
  26. << cloud->points[i].y << " "
  27. << cloud->points[i].z << std:: endl;
  28. }
  29. std:: cout << "原始点云数据点数:" << cloud->points.size()<< std:: endl << std:: endl;
  30. ///////****************************************************////////////////////
  31. ///////****************************************************////////////////////
  32. /*方法一:直通滤波器对点云进行处理。*/
  33. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>); //
  34. pcl::PassThrough<pcl::PointXYZ> passthrough;
  35. passthrough.setInputCloud(cloud); //输入点云
  36. passthrough.setFilterFieldName( "z"); //对z轴进行操作
  37. passthrough.setFilterLimits( 0.0, 400.0); //设置直通滤波器操作范围
  38. //passthrough.setFilterLimitsNegative(true);//true表示保留范围内,false表示保留范围外
  39. passthrough.filter(*cloud_after_PassThrough); //执行滤波,过滤结果保存在 cloud_after_PassThrough
  40. std:: cout << "直通滤波后点云数据点数:" << cloud_after_PassThrough->points.size() << std:: endl;
  41. ///////****************************************************////////////////////
  42. ///////****************************************************////////////////////
  43. /*方法二:体素滤波器实现下采样*/
  44. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_after_voxelgrid(new pcl::PointCloud<pcl::PointXYZ>); //
  45. pcl::VoxelGrid<pcl::PointXYZ> voxelgrid;
  46. voxelgrid.setInputCloud(cloud); //输入点云数据
  47. voxelgrid.setLeafSize( 10.0f, 10.0f, 10.0f); //AABB长宽高
  48. voxelgrid.filter(*cloud_after_voxelgrid);
  49. std:: cout << "体素化网格方法后点云数据点数:" << cloud_after_voxelgrid->points.size() << std:: endl;
  50. ///////****************************************************////////////////////
  51. ///////****************************************************////////////////////
  52. /*方法三:统计滤波器滤波*/
  53. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_after_StatisticalRemoval(new pcl::PointCloud<pcl::PointXYZ>); //
  54. pcl::StatisticalOutlierRemoval<pcl::PointXYZ> Statistical;
  55. Statistical.setInputCloud(cloud);
  56. Statistical.setMeanK( 20); //取平均值的临近点数
  57. Statistical.setStddevMulThresh( 5); //临近点数数目少于多少时会被舍弃
  58. Statistical.filter(*cloud_after_StatisticalRemoval);
  59. std:: cout << "统计分析滤波后点云数据点数:" << cloud_after_StatisticalRemoval->points.size() << std:: endl;
  60. ///////****************************************************////////////////////
  61. ///////****************************************************////////////////////
  62. /*方法四:条件滤波器*/
  63. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_after_Condition(new pcl::PointCloud<pcl::PointXYZ>);
  64. pcl::ConditionAnd<pcl::PointXYZ>:: Ptr range_condition(new pcl::ConditionAnd<pcl::PointXYZ>());
  65. range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr( new
  66. pcl::FieldComparison<pcl::PointXYZ>( "z", pcl::ComparisonOps::GT, 0.0))); //GT表示大于等于
  67. range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr( new
  68. pcl::FieldComparison<pcl::PointXYZ>( "z", pcl::ComparisonOps::LT, 0.8))); //LT表示小于等于
  69. pcl::ConditionalRemoval<pcl::PointXYZ> condition;
  70. condition.setCondition(range_condition);
  71. condition.setInputCloud(cloud); //输入点云
  72. condition.setKeepOrganized( true);
  73. condition.filter(*cloud_after_Condition);
  74. std:: cout << "条件滤波后点云数据点数:" << cloud_after_Condition->points.size() << std:: endl;
  75. ///////****************************************************////////////////////
  76. ///////****************************************************////////////////////
  77. /*方法五:半径滤波器*/
  78. pcl::PointCloud<pcl::PointXYZ>:: Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
  79. pcl::RadiusOutlierRemoval<pcl::PointXYZ> radiusoutlier; //创建滤波器
  80. radiusoutlier.setInputCloud(cloud); //设置输入点云
  81. radiusoutlier.setRadiusSearch( 100); //设置半径为100的范围内找临近点
  82. radiusoutlier.setMinNeighborsInRadius( 2); //设置查询点的邻域点集数小于2的删除
  83. radiusoutlier.filter(*cloud_after_Radius);
  84. std:: cout << "半径滤波后点云数据点数:" << cloud_after_Radius->points.size() << std:: endl;
  85. int a;
  86. std:: cin >> a;
  87. return ( 0);
  88. }

参考文献链接:https://blog.csdn.net/woniu199166/article/details/78625203

https://blog.csdn.net/zkl99999/article/details/44627911

,

本文主要介绍五中点云滤波方法:直通滤波器、体素滤波器、统计滤波器、条件滤波器、半径滤波器。

    原文作者:五大常用算法
    原文地址: https://blog.csdn.net/yanghan742915081/article/details/85092643
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞