PCL:StatisticalOutlierRemoval ❤️ 统计滤波

Posted 没事就要敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCL:StatisticalOutlierRemoval ❤️ 统计滤波相关的知识,希望对你有一定的参考价值。

1 原理

对每一点的邻域进行统计分析,基于点到所有邻近点的距离分布特征,过滤掉一些不满足要求的离群点。该算法对整个输入进行 两次迭代

在第一次迭代中,

  1. 对于点云中的每一个点,找到该点的K近邻;
  2. 计算每个点与它K近邻点的平局距离,结果满足高斯分布;
  3. 计算这些距离的均值 μ \\mu μ 和标准差 σ \\sigma σ
  4. 设置距离阈值 d t h r e s h o l d = μ ± k ⋅ σ d_{threshold}=\\mu±k·\\sigma dthreshold=μ±kσ k k k 为标准差乘数;

在下一次迭代中,如果点的平均邻域距离在区间 [ μ − k ⋅ σ , μ + k ⋅ σ ] [\\mu-k·\\sigma,\\mu+k·\\sigma] [μkσ,μ+kσ] ,则该点为内点,予以保留,区间外的点为噪声点,予以删除。

2 代码实现

代码:

#include <pcl/io/pcd_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{
	//--------------------------------- 加载点云 ---------------------------------
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);			//待滤波点云
	if (pcl::io::loadPCDFile("test.pcd", *cloud) < 0)
	{
		PCL_ERROR("\\a点云文件不存在!\\n");
		system("pause");
		return -1;
	}
	cout << "->加载点云中点的个数为:" << cloud->points.size() << endl;
	//============================================================================

	//--------------------------------- 统计滤波 ---------------------------------
	cout << "->正在进行统计滤波..." << endl;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);	//滤波后点云
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;	//创建滤波器对象
	sor.setInputCloud(cloud);				//设置待滤波点云
	sor.setMeanK(10);						//设置查询点的半径范围
	sor.setStddevMulThresh(3);				//设置判断是否为离群点的阈值,即半径内至少包括的点数
	//sor.setNegative(true);				//默认false,保存内点;true,保存滤掉的外点
	sor.filter(*cloud_filtered);			//执行滤波,保存滤波结果于cloud_filtered
	//============================================================================

	//------------------------------- 保存滤波点云 --------------------------------
	cout << "->正在保存滤波点云..." << endl;
	if (!cloud_filtered->empty())
	{
		pcl::io::savePCDFileBinary("StatisticalOutlierRemoval.pcd", *cloud_filtered);
		cout << "->滤波后点云中的点数为" << cloud_filtered->points.size() << endl;
	}
	else
	{
		PCL_ERROR("\\a滤波结果点云为空!\\n");
		system("pause");
		return -1;
	}
	//============================================================================


	//-------------------------- 滤波前后对比可视化(选) ---------------------------
	pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("统计滤波前后对比"));
	///原始点云
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
	viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
	viewer->addText("original_Pt", 10, 10, "v1_text", v1);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "original", v1);
	///半径滤波后点云
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
	viewer->addText("filtered_Pt", 10, 10, "v2_text", v2);
	viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered, "filtered", v2);
	///设置相关属性
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "original", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "filtered", v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "filtered", v2);

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
	//============================================================================

	return 0;
}

输出结果:

->加载点云中点的个数为:41049
->正在进行统计滤波...
->正在保存滤波点云...
->滤波后点云中的点数为40329

3 结果展示


相关链接:

PCL点云数据处理基础❤️❤️❤️目录

以上是关于PCL:StatisticalOutlierRemoval ❤️ 统计滤波的主要内容,如果未能解决你的问题,请参考以下文章

PCL的PCL语言

PCL系列——三维重构之贪婪三角投影算法

[pcl][转载]pcl在ubuntu上安装后测试代码

qt+pcl点云库

PCL系列——三维重构之移动立方体算法

vs2010 点云 pcl运行错误error2019