各种滤波器+可视化

一、原理分析

  在点云数据的处理过程中,滤波处理是点云预处理的第一步,只有在滤波预处理中将噪声点、离群点、孔洞、数据压缩等按照后续处理定制,才能够更好地进行配准、特征提取、曲面重建、可视化等后续应用处理。PCL中点云滤波模块提供了很多滤波处理算法,例如双边滤波、高斯滤波、条件滤波、直通滤波、基于随机采样一致性滤波等。
  需要进行点云滤波处理的情况:
  滤波有以下三种形式
  (1)噪声点、离群点
  在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,点云数据中将不可避免地出现一些噪声点,除了由于测量随机误差产生的噪声点外,由于受到外界干扰如视线遮挡障碍物等因素的影响,点云数据中往往还存在着一些远离主体点云的点,即离群点
  (2)因点云数据量太大需进行点云下采样,减少点云数量
  (3)点云数据密度不规则需要进行平滑处理

二、代码示例

1、使用passthrough(直通)滤波器对点云进行滤波处理

  直通滤波器就是在点云的属性上设置范围,对点云进行滤波,保留范围内的或保留范围外的。
  (1)指定一个维度以及该维度下的值域
  (2)遍历点云中的每个点,判断该点在指定维度上的取值是否在值域内,删除取值不在值域内的点
  (3)遍历结束,留下的点即构成滤波后的点云

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/pcl_visualizer.h>
//#include <pcl/io/pcd_io.h>
using namespace std;
int main()
{
   
	srand((unsigned int)time(NULL));//用系统时间初始化随机种子,防止每次随机数都一样
	//定义并实例化一个PointCloud指针对象(滤波前)
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//定义并实例化一个PointCloud指针对象(滤波后)
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
	
	//pcl::io::loadPCDFile("bunny.pcd", *cloud);//加载自己的数据

	//1、利用随机数生成点云,作为滤波的输入点云数据,并将其打印到标准输出

	cloud->width = 100;//点云数量
	cloud->height = 1;//表示无序点云
	cloud->points.resize(cloud->width * cloud->height);
	//填充点云数据
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
   
		cloud->points[i].x = rand() / (RAND_MAX + 1.0f);
		cloud->points[i].y = rand() / (RAND_MAX + 1.0f);
		cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
	}
	//输出上一步填充的点云的坐标
	cout << "滤波前:" << endl;
	for (size_t i = 0; i < cloud->points.size(); ++i)
		cout << "  " << cloud->points[i].x << " "
		<< cloud->points[i].y << " "
		<< cloud->points[i].z << endl;


	//2、接下来创建直通滤波器的对象,设置它的参数,滤波字段设置为Z轴方向,可接受的范围是(0.0,1.0),
	//即将点云中点的z坐标不在该范围内的删除或保留,由函数setFilterLimitsNegative决定

	pcl::PassThrough<pcl::PointXYZ> pass;// 创建滤波器对象
	pass.setInputCloud(cloud);           //设置输入点云
	pass.setFilterFieldName("z");        //按照点云数据的Z字段(Z坐标)进行过滤
	pass.setFilterLimits(0.0, 1.0);      //设置在过滤字段的范围(z坐标0-1)
	pass.setFilterLimitsNegative(true);  //设置保留范围内还是过滤掉范围内, 默认为flase,可以注释掉。true为过滤范围内的,flase为过滤掉范围外的
	pass.filter(*cloud_filtered);        //执行滤波,将完成过滤操作的点云数据保存在cloud_filtered中

	
	//3、打印输出完成过滤操作后的点云的坐标

	cout << "滤波后:" << endl;
	for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
		cout << "  " << cloud_filtered->points[i].x << " "
		<< cloud_filtered->points[i].y << " "
		<< cloud_filtered->points[i].z << endl;
	
	
	//4、可视化滤波前后的点云
	
	pcl::visualization::PCLVisualizer viewer("点云滤波前后");// 创建视窗对象
	//添加坐标系
	viewer.addCoordinateSystem(20);
	//创建左右窗口
	int v1(0);
	int v2(1);
	viewer.createViewPort(0.0, 0.0, 0.5, 1, v1);
	viewer.setBackgroundColor(0, 0, 0, v1);
	viewer.createViewPort(0.5, 0.0, 1, 1, v2);
	viewer.setBackgroundColor(0.5, 0.5, 0.5, v2);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_blue(cloud, 0, 0, 255); // 滤波前为蓝色点云
	viewer.addPointCloud(cloud, cloud_out_blue, "cloud_out1", v1);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_out_red(cloud_filtered, 250, 0, 0); //滤波后为红色点云
	viewer.addPointCloud(cloud_filtered, cloud_out_red, "cloud_out2", v2);
	
	while (!viewer.wasStopped())
	{
   
		viewer.spinOnce();
	}

	system("pause");
	return 0;
}

在这里插入图片描述

2、使用VoxelGrid(体素)滤波器对点云进行下采样

  体素滤波器在实现下采样同时不破坏点云本身几何结构,但会移动点的位置。可以去除一定程度的噪音点及离群点,主要功能是用来下采样。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值