点云学习----PCL点云滤波1-直通滤波

直通滤波:pcl::PassThrough类

        过滤掉点云某个纬度下指定区域内(或者外)的点,用于消除背景等操作。

        先来个自定义的点云数据滤波:

#include 
#include
#include
using namespace std;
int main()
{
    //定义一个点云对象和滤波后的点云对象
    pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
    pcl::PointCloud::Ptr cloud_filtered(new pcl::PointCloud);

    //用随机数添加点云数据
    srand(time(0));
    //指定点云数据大小
    cloud->width = 10;
    cloud->height = 1;
    cloud->points.resize(size_t(cloud->width) * size_t(cloud->height));
    for (size_t i = 0; i < cloud->size(); i++)
    {
        cloud->points[i].x = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].y = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
    }
    //查看一下创建好的点云数据
    cout << "The src cloud:" << endl;
    for (size_t i = 0; i < cloud->size(); i++)
    {
        cout << "x: " << cloud->points[i].x << " y: " << cloud->points[i].y << " z: " << cloud->points[i].z << endl;
    }
    /***********************************重点来了*********************************************************/
    //创建滤波器
    pcl::PassThrough pass;   //定义一个直通滤波类
    pass.setInputCloud(cloud);              //设置数据集
    pass.setFilterFieldName("z");           //指定滤波纬度
    pass.setFilterLimits(0.0, 0.2);         //指定滤波范围
    pass.setNegative(true);                 //true:过滤掉指定范围的点,保留范围外的点;false时相反
    pass.filter(*cloud_filtered);           //执行滤波,返回滤波后的数据
    /***********************************重点来了*********************************************************/

    //查看一下滤波后的点云数据
    cout << "The filter cloud:" << endl;
    for (size_t i = 0; i < cloud_filtered->size(); i++)
    {
        cout << "x: " << cloud_filtered->points[i].x << " y: " << cloud_filtered->points[i].y << " z: " << cloud_filtered->points[i].z << endl;
    }

    return 0;
}

pass.setNegative(true);   过滤掉z值为0-0.2的点

点云学习----PCL点云滤波1-直通滤波_第1张图片

 pass.setNegative(false);   过滤掉0-0.2以外的点

点云学习----PCL点云滤波1-直通滤波_第2张图片

         如何对多个纬度进行过滤?当然是先过滤一个纬度,然后将剩下的点再对另一个纬度进行过滤,这里可以通过点的索引进行处理。

 

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
//Demo2
int main()
{
	//定义对象指针
	pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
	pcl::PointCloud::Ptr cloud_filterd(new pcl::PointCloud);
	//加载pcd文件
	pcl::io::loadPCDFile("D:/bunny.pcd", *cloud);
	cout << "点云个数:" << cloud->size() << "个" << endl;
	//定义带参数(true)的直通滤波
	pcl::PassThrough pass(true);
	pass.setInputCloud(cloud);
	pass.setFilterFieldName("x");
	pass.setNegative(true);
	pass.setFilterLimits(0.0, 0.5);
	//保留下的数据索引
	std::vector indices_x;
	pass.filter(indices_x);

	//获取过滤掉的点的索引
	pcl::IndicesConstPtr indices_rem = pass.getRemovedIndices();


	pcl::IndicesPtr index_ptr_x = std::make_shared>(indices_x);
	//将保留下来的点的索引代替输入的数据集
	pass.setIndices(index_ptr_x);
	pass.setFilterFieldName("z");
	pass.setFilterLimits(0.0, 0.5);
	pass.setNegative(true);

	std::vector indices_xz;
	pass.filter(*cloud_filterd);
	cout << "点云个数:" << cloud_filterd->size() << "个" << endl;


	//显示对比
	boost::shared_ptr viewer(new pcl::visualization::PCLVisualizer("showcloud"));

	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	viewer->setBackgroundColor(0, 0, 0, v1);
	viewer->addText("Src data", 10, 10, "v1", v1);
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
	viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
	viewer->addText("filter data", 10, 10, "v2", v2);

	viewer->addPointCloud(cloud, "src cloud", v1);
	viewer->addPointCloud(cloud_filterd, "filterd cloud", v2);

	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "src cloud", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "filterd cloud", v2);

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));

	}

	return 0;
}

查看结果:

点云学习----PCL点云滤波1-直通滤波_第3张图片

点云学习----PCL点云滤波1-直通滤波_第4张图片 

 参考文献:

PCL 直通滤波器_点云侠的博客-CSDN博客_直通滤波原理

PCL滤波介绍(1) - Being_young - 博客园

你可能感兴趣的:(c++,pcl,点云,学习,c++)