久违的小分享(2)
PCL中基于统计的点云去噪
PCL中进行点云去噪的方法比较多,其中一种基于统计学的方法比较新颖,其函数为StatisticalOutlierRemoval。其原理是将输入数据中每个点到临近点的距离分布情况进行计算,得到各点到它所有临近点的平均距离。假设得到的结果是一个高斯分布,其形状由均值和标准差决定,平均距离在标准范围之外,就被定义为离群点而将其从数据集中删除。
其实现的关键代码进行说明:
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; // 创建滤波器对象
sor.setInputCloud(cloud); // 设置需要进行去噪的点云对象
sor.setMeanK(m); // 设置 m 为在进行统计时考虑查询点邻近点数
sor.setStddevMulThresh(1.0); // 设置距离阈值,
其公式是 mean + global stddev_mult * global stddev
sor.filter(*cloud_filtered); // 执行去噪计算并保存到 cloud_filtered
最后附上完整代码,以及不同参数设置时,滤波效果截图
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
void main() { pcl::PointCloud<pcl::PointXYZ>::Ptrcloud
(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptrcloud_filtered
(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile("E:\\table_scene_lms400.pcd",*cloud); pcl::visualization::PCLVisualizerviewer1("Cloud before filtering"); viewer1.setBackgroundColor(0,0, 0);//黑色背景 pcl::visualization::PointCloudColorHandlerCustom
<pcl::PointXYZ>before_color(cloud, 0, 255, 0); viewer1.addPointCloud<pcl::PointXYZ>(cloud,before_color, "before filter"); pcl::StatisticalOutlierRemoval<pcl::PointXYZ>sor; sor.setInputCloud(cloud); sor.setMeanK(50);//近邻点个数50 sor.setStddevMulThresh(1); sor.filter(*cloud_filtered); pcl::visualization::PCLVisualizerviewer2("After before filtering"); viewer2.setBackgroundColor(0,0, 0);//黑色背景
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>
after_color(cloud_filtered, 255, 0, 0); viewer2.addPointCloud<pcl::PointXYZ>
(cloud_filtered,after_color, "after filter");
while (!viewer1.wasStopped()|| !viewer2.wasStopped()) { viewer1.spinOnce(1); viewer2.spinOnce(1); } }
其中绿色点云是未进行滤波,红色点云是不同参数滤波后的图。
sor.setStddevMulThresh(0.5);
参数设置过小,导致边界点部分被剔除
sor.setStddevMulThresh(1);参数设置恰当,提取效果理想