当前位置: 首页 > news >正文

7.pcl滤波(一)

文章目录

  • 直通滤波
  • 体素滤波(下采样)
  • 均匀采样滤波
  • 统计滤波器
  • 半径滤波
  • 条件滤波器

直通滤波

#include <pcl/filters/passthrough.h>
// Create the filtering object
pcl::PassThrough<pcl::PointXYZ> pass; // 声明直通滤波
pass.setInputCloud(cloud); 			// 传入点云数据
pass.setFilterFieldName("z"); 		// 设置操作的坐标轴
pass.setFilterLimits(0.0, 3.0); 	// 设置坐标范围
pass.setFilterLimitsNegative(true); // 保留数据函数
pass.filter(*cloud_filtered);  		// 进行滤波输出
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>         // std::this_thread::sleep_for
#include <chrono>         // std::chrono::millisecondsint 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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1) {PCL_ERROR("Couldn't read file bunny.pcd \n");return (-1);}// 创建并配置直通滤波器pcl::PassThrough<pcl::PointXYZ> pass;pass.setInputCloud(cloud);pass.setFilterFieldName("z");pass.setFilterLimits(0.0, 1.0); // 设置Z轴范围pass.filter(*cloud_filtered);// 可视化设置pcl::visualization::PCLVisualizer viewer("PCL Visualizer");// 定义两个视图int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左边显示原始点云viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右边显示滤波后的点云// 添加原始点云到视图pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color_original(cloud, 0, 255, 0); // 绿色viewer.addPointCloud<pcl::PointXYZ>(cloud, single_color_original, "sample cloud original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud original");// 添加滤波后的点云到视图pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color_filtered(cloud_filtered, 255, 0, 0); // 红色viewer.addPointCloud<pcl::PointXYZ>(cloud_filtered, single_color_filtered, "sample cloud filtered", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud filtered");// 设置背景颜色viewer.setBackgroundColor(0, 0, 0, v1);viewer.setBackgroundColor(0, 0, 0, v2);// 主循环while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

体素滤波(下采样)

体素滤波(Voxel Grid Filter)是点云处理中一种常用的下采样方法,通过将三维空间划分为规则的体素网格,并用每个体素网格内的点集的一个代表点(通常是质心)来近似表示该体素内的所有点,从而减少数据量并降低计算复杂度

#include <pcl/filters/voxel_grid.h>pcl::VoxelGrid<pcl::PointXYZ> vg;		//创建滤波器对象vg.setInputCloud(cloud);				//设置待滤波点云vg.setLeafSize(0.05f, 0.05f, 0.05f);	//设置体素大小vg.filter(*cloud_filtered);	 //执行滤波,保存滤波结果于cloud_filtered
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1) {PCL_ERROR("Couldn't read file input.pcd \n");return (-1);}std::cerr << "Cloud before filtering: " << std::endl;std::cerr << *cloud << std::endl;// 创建并配置体素滤波器pcl::VoxelGrid<pcl::PointXYZ> sor;sor.setInputCloud(cloud);sor.setLeafSize(0.01f, 0.01f, 0.01f); // 设置体素大小为1cm*1cm*1cmsor.filter(*cloud_filtered);std::cerr << "Cloud after filtering: " << std::endl;std::cerr << *cloud_filtered << std::endl;// 可视化设置pcl::visualization::PCLVisualizer viewer("PCL Visualizer");// 定义两个视图int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左边显示原始点云viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右边显示滤波后的点云// 添加原始点云到视图pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color_original(cloud, 0, 255, 0); // 绿色viewer.addPointCloud<pcl::PointXYZ>(cloud, single_color_original, "sample cloud original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud original");// 添加滤波后的点云到视图pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color_filtered(cloud_filtered, 255, 0, 0); // 红色viewer.addPointCloud<pcl::PointXYZ>(cloud_filtered, single_color_filtered, "sample cloud filtered", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud filtered");// 设置背景颜色viewer.setBackgroundColor(0, 0, 0, v1);viewer.setBackgroundColor(0, 0, 0, v2);// 主循环while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

均匀采样滤波

pcl::UniformSampling 不是随机采样,而是一种基于体素空间下采样的均匀化方法。它通过在点云空间中构建一个三维体素网格,然后在每个非空体素中最多保留一个点(通常是该体素内第一个被处理的点),从而实现空间分布更均匀的下采样。

#include <pcl/keypoints/uniform_sampling.h>pcl::UniformSampling<pcl::PointXYZ> us;	//创建滤波器对象us.setInputCloud(cloud);				//设置待滤波点云us.setRadiusSearch(0.05f);				//设置滤波球体半径us.filter(*cloud_filtered);		//执行滤波,保存滤波结果于cloud_filtered
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/uniform_sampling.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>
#include <chrono>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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1){PCL_ERROR("Couldn't read file input.pcd \n");return (-1);}std::cerr << "Points before filtering: " << cloud->size() << std::endl;// 创建 UniformSampling 滤波器对象pcl::UniformSampling<pcl::PointXYZ> us;us.setInputCloud(cloud);us.setRadiusSearch(0.01); // 设置采样半径(即“体素”直径),单位:米us.filter(*cloud_filtered);std::cerr << "Points after filtering: " << cloud_filtered->size() << std::endl;// ================== 可视化 ==================pcl::visualization::PCLVisualizer viewer("Uniform Sampling - Before and After");int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 原始点云(绿色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);viewer.addPointCloud(cloud, green, "original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "original");// 滤波后点云(红色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(cloud_filtered, 255, 0, 0);viewer.addPointCloud(cloud_filtered, red, "uniform_sampled", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "uniform_sampled");viewer.setBackgroundColor(0, 0, 0);viewer.addText("Original", 10, 10, "v1_text", v1);viewer.addText("Uniform Sampling", 10, 10, "v2_text", v2);while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

统计滤波器

统计滤波(Statistical Outlier Removal, 简称 SOR)是点云处理中一种常用的去噪方法,用于移除离群点(outliers)。它基于这样一个假设:正常点周围的点密度较高,而离群点周围的邻居较少或距离较远,点云存在“毛刺”、“飞点”、“漂浮点”等噪声,统计滤波是一个非常推荐的预处理步骤。

#include <pcl/filters/statistical_outlier_removal.h>pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;	//创建滤波器对象sor.setInputCloud(cloud);				//设置待滤波点云sor.setMeanK(50);						//设置查询点近邻点的个数sor.setStddevMulThresh(1.0);			//设置标准差乘数,来计算是否为离群点的阈值//sor.setNegative(true);				//默认false,保存内点;true,保存滤掉的离群点sor.filter(*cloud_filtered);	//执行滤波,保存滤波结果于cloud_filtered
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>
#include <chrono>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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1){PCL_ERROR("Couldn't read file input.pcd \n");return (-1);}std::cerr << "Points before filtering: " << cloud->size() << std::endl;// 创建统计滤波器pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;sor.setInputCloud(cloud);sor.setMeanK(20);                    // 设置每个点查询的最近邻点数sor.setStddevMulThresh(1.0);         // 设置标准差倍数阈值sor.filter(*cloud_filtered);std::cerr << "Points after filtering: " << cloud_filtered->size() << std::endl;// ================== 可视化 ==================pcl::visualization::PCLVisualizer viewer("Statistical Outlier Removal");int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 原始点云(绿色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);viewer.addPointCloud(cloud, green, "original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "original");// 滤波后点云(蓝色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> blue(cloud_filtered, 0, 0, 255);viewer.addPointCloud(cloud_filtered, blue, "stat_filtered", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "stat_filtered");viewer.setBackgroundColor(0, 0, 0);viewer.addText("Original", 10, 10, "v1_text", v1);viewer.addText("After SOR", 10, 10, "v2_text", v2);// 主循环while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

半径滤波

半径滤波(Radius Outlier Removal, ROR)是点云处理中用于去除离群点的另一种方法。与统计滤波不同,它通过检查每个点周围指定半径内的邻居数量来判断该点是否为离群点。如果某个点在其指定半径内拥有的邻居数量少于设定的阈值,则认为该点为离群点并将其移除。

#include <pcl/filters/radius_outlier_removal.h>pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror;	//创建滤波器对象ror.setInputCloud(cloud);						//设置待滤波点云ror.setRadiusSearch(0.02);						//设置查询点的半径范围ror.setMinNeighborsInRadius(5);	//设置判断是否为离群点的阈值,即半径内至少包括的点数//ror.setNegative(true);	//默认false,保存内点;true,保存滤掉的外点ror.filter(*cloud_filtered);	//执行滤波,保存滤波结果于cloud_filtered
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>
#include <chrono>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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1){PCL_ERROR("Couldn't read file input.pcd \n");return (-1);}std::cerr << "Points before filtering: " << cloud->size() << std::endl;// 创建半径滤波器pcl::RadiusOutlierRemoval<pcl::PointXYZ> ror;ror.setInputCloud(cloud);ror.setRadiusSearch(0.05);  // 设置搜索半径为 5cmror.setMinNeighborsInRadius(2);  // 设置在给定半径内至少需要的邻居数为 2ror.filter(*cloud_filtered);std::cerr << "Points after filtering: " << cloud_filtered->size() << std::endl;// ================== 可视化 ==================pcl::visualization::PCLVisualizer viewer("Radius Outlier Removal");int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 原始点云(绿色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);viewer.addPointCloud(cloud, green, "original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "original");// 滤波后点云(蓝色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> blue(cloud_filtered, 0, 0, 255);viewer.addPointCloud(cloud_filtered, blue, "radius_filtered", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "radius_filtered");viewer.setBackgroundColor(0, 0, 0);viewer.addText("Original", 10, 10, "v1_text", v1);viewer.addText("After Radius Filter", 10, 10, "v2_text", v2);// 主循环while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

条件滤波器

#include <pcl/filters/conditional_removal.h>/*创建条件限定下的滤波器*/pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>());//创建条件定义对象range_cond//为条件定义对象添加比较算子range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(newpcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::GT, -0.1)));//添加在x字段上大于 -0.1 的比较算子range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(newpcl::FieldComparison<pcl::PointXYZ>("x", pcl::ComparisonOps::LT, 1.0)));//添加在x字段上小于 1.0 的比较算子pcl::ConditionalRemoval<pcl::PointXYZ> cr;	//创建滤波器对象cr.setCondition(range_cond);				//用条件定义对象初始化cr.setInputCloud(cloud);					//设置待滤波点云//cr.setKeepOrganized(true);				//设置保持点云的结构//cr.setUserFilterValue(5);					//将过滤掉的点用(5,5,5)代替cr.filter(*cloud_filtered);					//执行滤波,保存滤波结果于cloud_filtered

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
#include <thread>
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<pcl::PointXYZ>("D:/PCL/cloud/bunny.pcd", *cloud) == -1){PCL_ERROR("Couldn't read file input.pcd \n");return (-1);}std::cerr << "Points before filtering: " << cloud->size() << std::endl;// 创建条件滤波器pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZ>());range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::GT, 0.0))); // Z > 0.0range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZ>("z", pcl::ComparisonOps::LT, 1.0))); // Z < 1.0// 构建滤波器并应用条件pcl::ConditionalRemoval<pcl::PointXYZ> condrem;condrem.setCondition(range_cond);condrem.setInputCloud(cloud);condrem.setKeepOrganized(false); // 如果你的点云是有序的,请设置为true以保持结构化输出condrem.filter(*cloud_filtered);std::cerr << "Points after filtering: " << cloud_filtered->size() << std::endl;// ================== 可视化 ==================pcl::visualization::PCLVisualizer viewer("Conditional Removal");int v1(0), v2(1);viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);// 原始点云(绿色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);viewer.addPointCloud(cloud, green, "original", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "original");// 滤波后点云(蓝色)pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> blue(cloud_filtered, 0, 0, 255);viewer.addPointCloud(cloud_filtered, blue, "conditional_filtered", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "conditional_filtered");viewer.setBackgroundColor(0, 0, 0);viewer.addText("Original", 10, 10, "v1_text", v1);viewer.addText("After Conditional Filter", 10, 10, "v2_text", v2);// 主循环while (!viewer.wasStopped()){viewer.spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return 0;
}

在这里插入图片描述

http://www.lryc.cn/news/605387.html

相关文章:

  • IFCVF驱动+vhost-vfio提高虚拟机网络性能
  • 在线免疫浸润分析
  • Kimi-K2技术报告解读:万亿参数大模型,开源模型新SOTA
  • 如何判断一个数据库是不是出问题了?
  • STM32F1 Flash的操作
  • Python Day19 时间模块 和 json模块 及例题分析
  • C语言15-构造数据类型、位运算符、内存管理
  • 2018 年 NOI 最后一题题解
  • yolo8+阿里千问图片理解(华为简易版小艺看世界)
  • CSS 工作原理
  • 卡尔曼滤波通俗入门:预测、测量与最优融合
  • 重生之我在暑假学习微服务第五天《Docker部署项目篇》
  • 【人工智能99问】混合专家模型(MoE)是如何训练的?(18/99)
  • lesson28:Python单例模式全解析:从基础实现到企业级最佳实践
  • QT笔记--》QMenu
  • Java String类练习
  • 编程算法:从理论基石到产业变革的核心驱动力
  • 数字化转型-制造业未来蓝图:“超自动化”工厂
  • HTTPS基本工作过程:基本加密过程
  • List 接口
  • 基于动态权重-二维云模型的川藏铁路桥梁施工风险评估MATLAB代码
  • 人形机器人_双足行走动力学:基于OpenSim平台的股骨模型与建模
  • Python并发与性能革命:自由线程、JIT编译器的深度解析与未来展望
  • pytorch入门2:利用pytorch进行概率预测
  • C++中sizeof运算符全面详解和代码示例
  • sqli-labs:Less-5关卡详细解析
  • MySQL学习---分库和分表
  • vulhub ica1靶场攻略
  • GCC链接技术深度解析:性能与空间优化
  • VUE -- 基础知识讲解(二)