本篇内容
- 讲解统计滤波作用及原理
- 通过pcl实现统计滤波
- 强烈推荐在点云处理最开始使用,统计滤波处理,再送入其他算法进行处理!!!
效果:
1 主要原理
- 手动设置半径大小或者邻域点数量N(若设置的是半径大小,算法会搜索半径范围内的所有点;若设置邻域点数量N,算法会搜索距离最近的N个点);手动设置标准差倍率R
- 针对每个点,通过其邻域点计算出每个点的距离均值mean_d(欧式距离公式)
- 计算出全局的距离均值mean和标准差std
- 通过公式计算出距离阈值:distance_threshold=mean+std*R
- 遍历所有点,若该点的距离均值mean_d小于distance_threshold则保留,否则删除
PS:该算法从全局考虑,通过自身数据计算出阈值,标准差倍率也是相对值,具有很强的自适应效果,适用于大多数场景,强烈推荐使用
2 主要流程
初始化统计滤波器:
pcl::StatisticalOutlierRemoval<PointType> statistical_filter;
设置输入点云:
statistical_filter.setInputCloud(cloud);
设置邻域数量:
statistical_filter.setMeanK(10);
设置标准差倍率:
statistical_filter.setStddevMulThresh(3.0);
执行滤波:
statistical_filter.filter(*cloud_filter);
3 完整代码
#include <string>
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
// 前置点云类型,方便以后更改
using PointType = pcl::PointXYZ;
using PointCloud = pcl::PointCloud<PointType>;
using PointCloud_Ptr = PointCloud::Ptr;
int main(int argc, char **argv) {
if (argc < 3) {
std::cout<<"Usage: ./read_pcd <pcd_file_path> <pcd_save_path>\n";
return -1;
}
std::string pcd_file_path(argv[1]);
std::string pcd_save_path(argv[2]);
// 声明变量,用于保存点云数据
PointCloud_Ptr cloud(new PointCloud);
PointCloud_Ptr cloud_filter(new PointCloud);
// 读取pcd点云文件
if (pcl::io::loadPCDFile<PointType>(pcd_file_path, *cloud) == -1) {
std::cerr<<"check pcd path\n";
return -1;
}
// 初始化统计滤波器
pcl::StatisticalOutlierRemoval<PointType> statistical_filter;
// 设置输入点云
statistical_filter.setInputCloud(cloud);
// 设置邻域数量
statistical_filter.setMeanK(10);
// 设置标准差倍率
statistical_filter.setStddevMulThresh(3.0);
// 执行滤波
statistical_filter.filter(*cloud_filter);
pcl::io::savePCDFileASCII(pcd_save_path, *cloud_filter);
return 0;
}