PCL使用RadiusOutlierRemoval进行过滤

这篇博客记录了使用PCL库进行点云处理的过程,特别是通过RadiusOutlierRemoval算法去除噪声点。作者初始化了一个随机点云,设置搜索半径为100,并要求每个点周围至少有3个邻居点,以此来过滤异常值。在调试过程中,通过调整参数和实时查看可视化结果,解决了点云显示问题。最后展示了输入和输出点云的数目,并通过PCLVisualizer进行可视化验证效果。
摘要由CSDN通过智能技术生成
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
int	main (int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr my_cloud (new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr my_cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);

	//pcl::PCDReader my_reader;
	//my_reader.read<pcl::PointXYZ>("E:\\vs_code\\hello_pcl\\hello_pcl\\table_scene_lms400.pcd",*my_cloud);
	my_cloud->width = 1000;
	my_cloud->height = 1;
	my_cloud->points.resize(my_cloud->width*my_cloud->height);
	for (size_t i = 0; i < my_cloud->points.size(); ++i)
	{
		my_cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
		my_cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
		my_cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
	}

	for (size_t i = 0; i < my_cloud->points.size(); ++i)
	{
		std::cout<<my_cloud->points[i].x<<" "
			<<my_cloud->points[i].y<<" "
			<<my_cloud->points[i].z<<std::endl;
	}

	pcl::RadiusOutlierRemoval<pcl::PointXYZ> routrem;
	routrem.setInputCloud(my_cloud);
	routrem.setRadiusSearch(100);
	routrem.setMinNeighborsInRadius(3);
	routrem.filter(*my_cloud_filtered);

	std::cout<<"输入的点云个数: "<<my_cloud->points.size()<<std::endl;
	std::cout<<"输出的点云个数: "<<my_cloud_filtered->points.size()<<std::endl;

	pcl::visualization::PCLVisualizer my_viewer1;
	pcl::visualization::PCLVisualizer my_viewer2; 
	my_viewer1.addPointCloud(my_cloud);
	my_viewer2.addPointCloud(my_cloud_filtered);
	while(!my_viewer1.wasStopped())
	{
		my_viewer1.spinOnce(100);
		my_viewer1.spinOnce(100);
	}
	return (0);
}

虽然代码不多,但是还是遇到了一些坑,这里做个简单的记录,写写心得

	pcl::RadiusOutlierRemoval<pcl::PointXYZ> routrem;
	routrem.setInputCloud(my_cloud);
	routrem.setRadiusSearch(100);
	routrem.setMinNeighborsInRadius(3);
	routrem.filter(*my_cloud_filtered);

这一块就是核心的内容了,依旧是设置点云、计算结果,不同之处就是设置了:搜索半径范围、半径内最小的点数,就是说:在设置的100的半径范围内,对于临近点少于3个的点,进行去除

这里记录一点心得,起初我是按照别人的教程来的,设置的搜索半径太小,记得是0.3吧,然后运行好几次都没有点显示,最后我就加了循环,看看生成的点的半径是什么样子,这确实是一个调试的好方法,及时看看输出的结果!
另外的话,可以看到,我每次都是利用可视化把结果显示了,我觉得这也是一个很好的调试方法

最后放一下输出的结果
原始点云
过滤之后的点云图
终端输出

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
使用PCL实现过滤空间任一角度矩形点云,可以使用PCL库提供的CropBox滤波器。CropBox滤波器可以根据一个定向的矩形框来滤波点云。下面是实现的步骤: 1. 创建一个PointCloud对象存储点云数据,假设为cloud。 2. 创建一个CropBox滤波器对象,假设为cropBox。 3. 设置CropBox滤波器的参数。需要设置矩形框的中心点、长、宽、高以及旋转角度。可以使用Eigen库提供的Affine3d对象来设置旋转角度。 4. 应用CropBox滤波器,将滤波后的点云存储在另一个PointCloud对象中,假设为cloud_filtered。 下面是示例代码: ```cpp #include <pcl/filters/crop_box.h> // 1. 创建PointCloud对象存储点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 2. 创建CropBox滤波器对象 pcl::CropBox<pcl::PointXYZ> cropBox; // 3. 设置CropBox滤波器的参数 cropBox.setMin(Eigen::Vector4f(-1.0, -1.0, -1.0, 1.0)); // 矩形框最小值 cropBox.setMax(Eigen::Vector4f(1.0, 1.0, 1.0, 1.0)); // 矩形框最大值 Eigen::Affine3d transform = Eigen::Affine3d::Identity(); // 旋转矩阵 transform.rotate(Eigen::AngleAxisd(M_PI/4, Eigen::Vector3d::UnitZ())); // 绕z轴旋转45度 transform.translation() << 1, 1, 0; // 平移向量 cropBox.setTransform(transform); // 设置旋转矩阵和平移向量 // 4. 应用CropBox滤波器 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); cropBox.setInputCloud(cloud); cropBox.filter(*cloud_filtered); ``` 其中,setMin()和setMax()方法用于设置矩形框的最小值和最大值。Eigen::Vector4f表示一个四维向量,前三个分量表示矩形框的长、宽、高,第四个分量默认为1.0。setTransform()方法用于设置旋转矩阵和平移向量。Eigen::Affine3d表示一个仿射变换矩阵,可以使用rotate()方法设置旋转角度,使用translation()方法设置平移向量。setInputCloud()方法用于设置输入点云,filter()方法用于应用滤波器,并将滤波后的点云存储在指定的PointCloud对象中。 如果要对任意角度的矩形进行滤波,可以根据矩形的中心点、长、宽、高和旋转角度来计算出矩形框的最小值和最大值。具体实现方法可以参考以下代码: ```cpp // 假设矩形的中心点为(1, 1, 0),长为2,宽为1,高为1,绕z轴旋转45度 Eigen::Vector3d center(1, 1, 0); Eigen::Vector3d length(2, 1, 1); Eigen::Quaterniond rotation(Eigen::AngleAxisd(M_PI/4, Eigen::Vector3d::UnitZ())); // 计算矩形框的最小值和最大值 Eigen::Vector3f minPt, maxPt; Eigen::Vector3d maxLength = rotation*length; minPt << center - 0.5*maxLength.cast<float>(); maxPt << center + 0.5*maxLength.cast<float>(); ``` 其中,center表示矩形的中心点,length表示矩形的长、宽、高,rotation表示旋转角度。使用Quaterniond对象来表示旋转角度,可以使用AngleAxisd构造函数来构造一个旋转轴和旋转角度,然后将其转换成四元数形式。使用*运算符来对向量进行旋转变换。最后,根据矩形的最小值和最大值来设置CropBox滤波器的参数即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值