1pcl滤波模块架构
以pcl::Filter<PointT>
为基类,衍生出各种滤波算法派生类,结构如下图所示:
2滤波基类与滤波派生类调用
pcl::Filter<PointT>
是几乎是所有滤波算法的接口,在pcl::Filter<PointT>
基类中,最重要的函数为void filter (PointCloud &output)
,在我们常用的pcl统计滤波、体素滤波、半径滤波等等,在都会调用基类的该】filter函数,例如统计滤波:
// Create the filtering object
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud (cloud);
sor.setMeanK (50);
sor.setStddevMulThresh (1.0);
sor.filter (*cloud_filtered);
filter()函数的实现如下:
inline void
filter (PointCloud &output)
{
if (!initCompute ())
return;
if (input_.get () == &output) // cloud_in = cloud_out
{
PointCloud output_temp;
applyFilter (output_temp);
output_temp.header = input_->header;
output_temp.sensor_origin_ = input_->sensor_origin_;
output_temp.sensor_orientation_ = input_->sensor_orientation_;
pcl::copyPointCloud (output_temp, output);
}
else
{
output.header = input_->header;
output.sensor_origin_ = input_->sensor_origin_;
output.sensor_orientation_ = input_->sensor_orientation_;
applyFilter (output);
}
deinitCompute ();
}
在filter中调用了applyFilter()
函数,这里的applyFilter()
函数为各个滤波算法的具体实现,applyFilter()
是虚函数,在基类为纯虚函数:virtual void applyFilter (PointCloud &output) = 0;
,在各个滤波派生类中实现了具体的方法。正常情况下,派生类可以调用基类的成员函数,这里值得注意的是,基类通过纯虚函数反过来调用了派生类的成员函数,对于filter模块来说不失为好的设计模式,值得学习。
3pcl滤波算法总览
pcl滤波算法主要分为三类:
滤波类、采样类、空间裁剪器、其他
3.1滤波类
(1)双边滤波,快速双边滤波,omp加速的快速双边滤波(pcl中双边滤波需要使用强度信息)
bilateral.hpp
fast_bilateral.hpp
fast_bilateral_omp.hpp
(2)半径滤波
radius_outlier_removal.hpp
(3)中值滤波
median_filter.hpp
(4)统计滤波
statistical_outlier_removal.hpp
(5)直通滤波、条件滤波
这两种原理上是一致的,都是根据点的属性(filed)例如xyz法线曲率直方图属性等进行过滤
passthrough.hpp
conditional_removal.hpp
(6)模型滤波
设置特定模型做为过滤器,根据设定的模型(如线面体)进行拟合,以此提取该模型的点云
model_outlier_removal.hpp
(7)投影滤波
设置特定几何模型做为过滤器,将点云投影至该模型
project_inliers.hpp
(8)形态学滤波
对点云进行开闭操作
morphological_filter.hpp
(9)最小z值采样
对点云建立二维网格,取网格中z值最小的点,可以用于分析多回波信息,提取地面
grid_minimum.hpp
(10)局部最大z值采样
对点云进行半径进行搜索,删除近邻中z值最大的点,可以用于提取地面
local_maximum.hpp
3.2采样类(多用于配准或者点云其他后处理)
(1)体素采样
4种体素滤波
approximate_voxel_grid.hpp
voxel_grid.hpp
voxel_grid_covariance.hpp ["The Three-Dimensional Normal-Distributions Transform an Efficient Representation for Registration"]
voxel_grid_label.cpp
(2)均匀采样
uniform_sampling.hpp
(3)随机采样
random_sample.hpp
(4)体素法线采样
将输入空间划分为网格,直到每个网格最多包含N个点,并在每个网格内随机采样点。
使用每个网格的N个点计算得到一个法线。在栅格内采样的所有点的法线都等于该法线。
sampling_surface_normal.hpp
(5)法线空间均匀采样(NSS)
将点云在法向空间中排列,然后对点云进行均匀采样
normal_space.hpp[“Efficient variants of the ICP algorithm”]
(6)基于6D协方差的点云采样
该算法以增量方式向生成的点云添加点,同时尽量使协方差矩阵的所有6个特征值彼此尽可能接近
covariance_sampling.hpp["Geometrically Stable Sampling for the ICP Algorithm"]
(7)金字塔采样
有组织点云的多尺度表示方法。这是一种迭代平滑降采样算法。
pyramid.hpp
3.3空间裁剪器
(1)锥体裁剪器
截锥体剔除过滤截锥体内由相机姿态和视野给定的点。
frustum_culling.hpp
(2)仿射变换3D包围盒裁剪器
需要给定一个仿射变换矩阵,将原点的单位包围盒进行仿射变换,得到仿射变换后的包围盒内的点云
box_clipper3D.hpp
(3)平面裁剪器
plane_clipper3D.hpp
(4)包围盒裁剪器
获取指定包围盒内的点云
crop_box.hpp
(5)凸包裁剪器
首先建立凸包,获取在3D封闭曲面上或2D封闭多边形内或外部的点云
crop_hull.hpp
3.4其他
(1)法线优化
每个法线更新为其邻域中所有法线的(加权)平均值,以此来优化已估计的法线。
normal_refinement.hpp
(2)点云卷积
convolution.hpp
convolution_3d.hpp
(3)提取索引点云
extract_indices.hpp
(4)估计遮挡区域
voxel_grid_occlusion_estimation.hpp['John Amanatides and Andrew Woo, A Fast Voxel Traversal Algorithm for Ray Tracing']
(5)移除边不连续上出现的重影点
shadowpoints.hpp