利用PCL库通过C++实现点云滤波

直通滤波器

void passthrough(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_PassThrough,float rangelow, float rangehigh, string dimension) {

	//方法1:直通滤波器对点云处理
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PassThrough<pcl::PointXYZ> passthrough;
	passthrough.setInputCloud(cloud);//输入点云
	passthrough.setFilterFieldName(dimension);//对z轴进行操作
	passthrough.setFilterLimits(rangelow, rangehigh);//设置直通滤波器操作范围
	//passthrough.setFilterLimitsNegative(true);//true表示保留范围内,false表示保留范围外
	passthrough.filter(*cloud_after_PassThrough);//执行滤波,过滤结果保存在 cloud_after_PassThrough
}

体素滤波器

void voxelgrid(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_voxelgrid, float length, float width, float heigth) {

	//方法2:体素滤波器实现下采样
	pcl::VoxelGrid<pcl::PointXYZ> voxelgrid;
	voxelgrid.setInputCloud(cloud);//输入点云数据
	voxelgrid.setLeafSize(length, width, heigth);//AABB长宽高
	voxelgrid.filter(*cloud_after_voxelgrid);
}

统计滤波器

void Statistical(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_StatisticalRemoval, float averagepoint, float droppoint) {

	//方法3:统计滤波器滤波
	// 创建滤波器,对每个点分析的临近点的个数设置为50 ,并将标准差的倍数设置为1  这意味着如果一
    //个点的距离超出了平均距离一个标准差以上,则该点被标记为离群点,并将它移除,存储起来
	pcl::StatisticalOutlierRemoval<pcl::PointXYZ> Statistical; //创建滤波器对象
	Statistical.setInputCloud(cloud); //设置待滤波的点云
	Statistical.setMeanK(averagepoint); //设置在进行统计时考虑查询点临近点数
	Statistical.setStddevMulThresh(droppoint); //设置判断是否为离群点的阀值
	Statistical.filter(*cloud_after_StatisticalRemoval); //存储
}

条件滤波器

void range_condition(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_Condition, float rangelow, float rangehigh, string dimension){
	//方法4:条件滤波器 (其实和直通滤波器差不多)
	
	pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_condition(new pcl::ConditionAnd<pcl::PointXYZ>());
	range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
		pcl::FieldComparison<pcl::PointXYZ>(dimension, pcl::ComparisonOps::GT, rangelow)));
		GT表示大于 、EQ表示等于、LT表示小于、GE表示大于或等于、LE表示小于或等于
	range_condition->addComparison(pcl::FieldComparison<pcl::PointXYZ>::ConstPtr(new
		pcl::FieldComparison<pcl::PointXYZ>(dimension, pcl::ComparisonOps::LT, rangehigh)));  //LT表示小于等于
	//创建滤波器并用条件定义对象初始化
	pcl::ConditionalRemoval<pcl::PointXYZ> condition;
	condition.setCondition(range_condition);
	condition.setInputCloud(cloud);                   //输入点云
	condition.setKeepOrganized(false); //设置是否保留滤波后删除的点,以保持点云的有序性,通过setuserFilterValue设置的值填充点云,
	//或从点云中删除滤波后的点,从而改变其组织结构.	如果设置为true且不设置setUserFilterValue的值,则用nan填充点云
	condition.filter(*cloud_after_Condition);

}

半径滤波器

void radiusoutlier(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_Radius, float radius, int point) {
	//方法5:半径滤波器 (类似统计滤波器但效果不如统计)
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_Radius(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::RadiusOutlierRemoval<pcl::PointXYZ> radiusoutlier;  //创建滤波器
	radiusoutlier.setInputCloud(cloud);    //设置输入点云
	radiusoutlier.setRadiusSearch(radius);     //设置半径为100的范围内找临近点
	radiusoutlier.setMinNeighborsInRadius(point); //设置查询点的邻域点集数小于2的删除
	radiusoutlier.filter(*cloud_after_Radius);
}

双边滤波器

//该类的实现利用的并非XYZ字段的数据进行,而是利用强度数据进行双边滤波算法的实现
void bilateralFilter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_bilateralFilter,float sigma_s, float sigma_r){
	//方法6:双边滤波法(该滤波方法一般适用于有序点云,在此demo中不适用)
	// Apply the filter

	//(1)如果点云是有序的,通过 pcl: : Organ izedDatalnd ex 使用有序搜索方法 。  
	//(2 ) 如果点云是无序的,通过 pcl : : KdTreeFLANN 使用通用的 Kd 树
	//有序点云  
	//Example:  
	//  cloud.width = 640; // Image-like organized structure, with 640 rows and 480 columns,  
	//  cloud.height = 480; // thus 640*480=307200 points total in the dataset 
	//无序点云  
	//Example:  
	//  cloud.width = 307200;  
	//  cloud.height = 1; // unorganized point cloud dataset with 307200 points  
	pcl::FastBilateralFilter<pcl::PointXYZ> fastbilateralfilter;
	fastbilateralfilter.setInputCloud(cloud);
	fastbilateralfilter.setSigmaS(sigma_s);
	fastbilateralfilter.setSigmaR(sigma_r);
	fastbilateralfilter.filter(*cloud_after_bilateralFilter);//存储滤波后的数据格式

}

高斯滤波器

void  Gaussianfilter(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_after_GaussianFilter, float radius) {
	//Set up the Gaussian Kernel
	pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ>::Ptr kernel(new pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ>);
	(*kernel).setSigma(4);
	(*kernel).setThresholdRelativeToSigma(4);
	cout << "Kernel made" << endl;

	//Set up the KDTree
	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
	(*kdtree).setInputCloud(cloud);
	cout << "KdTree made" << endl;


	//Set up the Convolution Filter
	pcl::filters::Convolution3D <pcl::PointXYZ, pcl::PointXYZ, pcl::filters::GaussianKernel<pcl::PointXYZ, pcl::PointXYZ> > convolution;
	convolution.setKernel(*kernel);
	convolution.setInputCloud(cloud);
	convolution.setSearchMethod(kdtree);
	convolution.setRadiusSearch(radius);
	convolution.setNumberOfThreads(10);//important! Set Thread number for openMP
	cout << "Convolution Start" << endl;
	convolution.convolve(*cloud_after_GaussianFilter);
	cout << "Convoluted" << endl;

}

关于以上几种点云滤波方法的原理和适用情况将在之后的博客中说明

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCL(点云)是一种用于处理三维点云数据的开源。在PCL中,点云滤波是一种通过对点云数据进行处理来去除噪音和无效点的方法。下面是一个示例代码,用于使用PCL进行离群点滤波和统计滤波。 首先,需要包含PCL的头文件: ```cpp #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/statistical_outlier_removal.h> #include <pcl/filters/voxel_grid.h> ``` 然后,定义一个主函数,在其中读取点云数据文件并应用滤波器: ```cpp int main() { // 创建点云数据对象 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 从磁盘读取点云数据文件 if (pcl::io::loadPCDFile<pcl::PointXYZ>("/path/to/pointcloud.pcd", *cloud) == -1) { PCL_ERROR("Couldn't read file!"); return -1; } // 创建离群点滤波器对象 pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setInputCloud(cloud); sor.setMeanK(50); // 用于计算每个点邻域的均值的点数 sor.setStddevMulThresh(1.0); // 标准差倍数阈值 sor.filter(*cloud); // 应用滤波器 // 创建体素(体素网格)滤波器对象 pcl::VoxelGrid<pcl::PointXYZ> vg; vg.setInputCloud(cloud); vg.setLeafSize(0.01, 0.01, 0.01); // 设置体素的大小 vg.filter(*cloud); // 应用滤波器 // 输出滤波后的点云数据 std::cout << "Filtered point cloud contains " << cloud->size() << " data points." << std::endl; return 0; } ``` 上述代码首先创建了一个点云数据对象,并从磁盘读取点云数据文件。然后,创建了一个离群点滤波器对象,并设置相关参数。接着,将点云数据传递给离群点滤波器,并应用滤波器进行滤波。之后,创建了一个体素滤波器对象,并设置相关参数。将点云数据传递给体素滤波器,并应用滤波器进行滤波。最后,输出滤波后的点云数据的数量。 这段代码演示了如何使用PCL进行点云滤波。在实际应用中,可以根据特定需求选择不同的滤波方法和参数进行更精确的处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值