PCL统计滤波:

统计滤波器:

统计滤波器主要用于去除明显离群点。 离群点特征在空间中分布稀疏。定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。根据给定均值与方差,可剔除方差之外的点。

对于图中那些离点云规模较聚集的区域,简称为离群点,统计滤波对这些离群点的处理比较好。

        在官方文档里有下面这张图片,可以看出统计滤波器对离群点的处理效果还是比较好的。

 

 

#include <iostream>
#include <pcl/io/pcd_io.h>//pcd读写类相关头文件
#include <pcl/point_types.h>//支持点类型头文件
#include <pcl/filters/statistical_outlier_removal.h>//统计滤波器支持头文件
#include <pcl/visualization/cloud_viewer.h>//可视化
#include <pcl/io/io.h>//输入输出头文件
#include <pcl/visualization/pcl_visualizer.h>  //PCL可视化的头文件

boost::shared_ptr<pcl::visualization::PCLVisualizer> simpleVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)//创建boost shared_ptr共享指针
{
	//创建3D窗口并添加点云
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));//窗口显示
	viewer->setBackgroundColor(135, 206, 250);//设置背景颜色为淡蓝色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 190, 32, 230);//设置点云颜色为粉色
	viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");//将点云颜色信息添加显示
	//viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");//设置点云点的大小
	viewer->addCoordinateSystem(1.0);//添加坐标系
	viewer->initCameraParameters();//设置照相机参数,使用户从默认的角度和方向观察点云

	return (viewer);//返回viewer
}



int main(int argc, char** argv)
{
	pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());
	pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());
	pcl::PointCloud <pcl::PointXYZ>::Ptr cloudxyz(new pcl::PointCloud<pcl::PointXYZ>);//创建cloudxyz指针

	
	// 填入点云数据
	pcl::PCDReader reader;//pcd文件读操作
	// 把路径改为自己存放文件的路径
	reader.read("D:\\pclcode\\filter\\statistical_removal\\source\\table_scene_lms400.pcd", *cloud);//读取文件夹中的点云文件
	std::cerr << "Cloud before filtering: " <<  cloud->width * cloud->height
		<< " data points (" << pcl::getFieldsList(*cloud) << ")." << endl;//显示滤波前点云文件的总点数


	// 创建滤波器对象
	pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> sor;//创建统计滤波器对象
	sor.setInputCloud(cloud);//色湖之输入点云
	sor.setMeanK(50);//设置考虑查询点临近个数
	//sor.setMeanK(100);//设置考虑查询点临近个数
	sor.setStddevMulThresh(1.0);//设置判断是否为离群点的阈值
	sor.filter(*cloud_filtered);//执行滤波,并将结果保存在clloud_filterd
	std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
		<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")." << endl;//输出滤波后的点云总点数

	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;//创建指针
	//pcl::fromPCLPointCloud2(*cloud, *cloudxyz);//显示滤波前的点云
	pcl::fromPCLPointCloud2(*cloud_filtered, *cloudxyz);//显示滤波后的点云

	viewer = simpleVis(cloudxyz);
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
	system("pause");
	return (0);


}
//sor.setMeanK(50);//设置考虑查询点临近个数
//Cloud before filtering : 460400 data points(x y z intensity distance sid).
//PointCloud after filtering : 451474 data points(x y z intensity distance sid).
//sor.setMeanK(100);//设置考虑查询点临近个数
//Cloud before filtering : 460400 data points(x y z intensity distance sid).
//PointCloud after filtering : 447507 data points(x y z intensity distance sid).

 

CmakeLists文件:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(statistical_removal)

find_package(PCL 1.2 REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})

link_directories(${PCL_LIBRARY_DIRS})

add_definitions(${PCL_DEFINITIONS})

add_executable (statistical_removal statistical_removal.cpp)

target_link_libraries (statistical_removal ${PCL_LIBRARIES})

原始点云文件:

 

sor.setMeanK(50);//设置考虑查询点临近个数50

执行效果:

 

sor.setMeanK(100);//设置考虑查询点临近个数100

执行效果:

 

 

#include <iostream>
#include <pcl/point_types.h>//pcl支持点类型头文件
#include <pcl/point_cloud.h>//点云头文件
#include <pcl/io/pcd_io.h>//pcd读写类输入输出头文件
#include <pcl/visualization/pcl_visualizer.h>//可视化头文件
#include <pcl/filters/statistical_outlier_removal.h>//统计滤波器头文件

using namespace std;

int main(int argc,char **argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
	if (pcl::io::loadPCDFile("D:\\pclcode\\filter\\statistical_removal\\source\\scan_010.pcd", *cloud) == -1)//点云文件读取
	{
		cout << "Could not read the point cloud file scan_010.pcd \n";
		system("pause");
		return (-1);
	}
	cout << "原始点云总个数:" << cloud->size() << endl;//输出原始点云的总点数

	// 定义滤波器
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;//创建统计滤波器对象
	sor.setInputCloud(cloud);//设置输入点云
	sor.setMeanK(50);   //设置在进行统计时考虑查询点邻近点数
	//sor.setMeanK(100);   //设置在进行统计时考虑查询点邻近点数100
	sor.setStddevMulThresh(1.0); //设置判断是否为离群点的阈值,如果一个点的距离超出平均距离一个标准差以上,则该点被标记为离群点,并将被移除。
	//sor.setStddevMulThresh(2.0);//设置判断是否为离群点的阈值,如果一个点的距离超出平均距离一个标准差以上,则该点被标记为离群点,并将被移除
	sor.filter(*cloud_filtered);//执行滤波,并将结果储存在cloud_filtered中

	//显示点云
	pcl::visualization::PCLVisualizer viewer("点云3D可视化");//可视化窗口
	cout << "统计滤波之后点云的个数:" << cloud_filtered->size() << endl;//统计滤波后点云文件的总点数

	int v1(0);//左边第一个窗口
	viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);//xmin, ymin, xmax, ymax,取值范围0-1
	viewer.setBackgroundColor(0, 0, 0, v1);//设置背景为黑色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green0(cloud, 0, 225, 0);//设置点云显示为绿色
	viewer.addPointCloud(cloud, green0, "cloud", v1);//添加点云

	int v2(0);//右边第二个窗口
	viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);//xmin, ymin, xmax, ymax,取值范围0-1
	viewer.setBackgroundColor(0.3, 0.3, 0.3, v2);//设置背景颜色为灰色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green1(cloud_filtered, 0, 225, 0);//设置点云显示为绿色
	viewer.addPointCloud(cloud_filtered, green1, "cloud_filtered", v2);//添加点云

	while (!viewer.wasStopped()) {
		viewer.spinOnce(100);
	}
	system("pause");
	return 0;
}
//sor.setMeanK(50);  
//sor.setStddevMulThresh(1.0);
//原始点云总个数:1716575
//sor.setMeanK(50);  
//sor.setStddevMulThresh(2.0);
//统计滤波之后点云的个数:1641517
//原始点云总个数:1716575
//统计滤波之后点云的个数:1685130

 CmakeLists文件:(同上)

//sor.setStddevMulThresh(1.0);

设置阈值为1的效果:

//sor.setStddevMulThresh(2.0);

设置阈值为2的效果:

 

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长沙有肥鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值