PCL点云数据处理-滤波基础(C++)

OK,本篇作为PCL学习笔记,希望同道之人互相交流、讨论!有误之处希望指出,欢迎留言

PCL库中包含几个重要的模块库:FIilter(过滤器)、Features(特征)、Keypoints(关键点)、Registration(配准)、Kd-treeOctree(八叉树)、Segementation(分割)、Sample consensus(样本一致性)、Surface(表面)、Range image(深度图)、I/O(输入输出)、Visualization(可视化)、Common(公共)、Search(搜索)

Filter模块库:去除点云中不需要的点和点云的投影。

下面用不同方法对点云进行滤波处理:

目录

  1. Passthrough Filter(直通滤波):
  2. VoxelGrid Filter(体素化网格滤波):
  3. StatisticalOutlierRemoval(统计学的(稀疏)离群点去除):
  4. Projecting points using a parameter model(投影滤波):
  5. Extracting indices from a PointCloud(点云索引提取点云子集):
  6. RadiusOutlierRemoval或ConditionalRemoval滤波器:

1.Passthrough Filter(直通滤波):限定某个字段(理解为点云的变量参数)的范围来达到去除异常点效果关键:

步骤:输入点云-创建滤波器对象-设置字段范围-保存滤波后点云

头文件:#include<pcl/filters/passthrough.h>

代码:pcl::PassThrough<pcl::PointXYZ>pass;//创建滤波器对象
      pass.setInputCloud(cloud);          //调用成员函数输入点云,cloud为已创建的点云对象
      pass.setFilterFieldName("z");       //调用设置字符串函数,z为设定字段对应字符串
      pass.setFilterLimits(0,2.0);        //调用范围设置函数,z的范围在0-2
      pass.filter(*cloud_filtered);      //执行直通过滤,并将执行结果被保存在cloud_filtered

 完整代码(直通滤波):

#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>

int main(int argc, char** argv)
{
    srand(time(0));
    //创建点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
    //填入点云数据
    cloud->width = 5;
    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) - 0.5;
        cloud->points[i].y = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
    }

      std::cerr << "Cloud before filtering: " << std::endl;
    for (const auto& point : *cloud)
        std::cerr << "    " << point.x << " "
        << point.y << " "
        << point.z << std::endl;

    //直通滤波----
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(0,1.0);
    pass.filter(*cloud_filtered);
    //滤波结束,结果保存在cloud_filtered

    std::cerr << "Cloud after filtering: " << std::endl;
    for (const auto& point : *cloud_filtered)
        std::cerr << "    " << point.x << " "
        << point.y << " "
        << point.z << std::endl;
    return (0);
}

执行结果

Cloud before filtering:
    -0.0164185 -0.177155 0.0244751
    -0.194244 0.169983 -0.147095
    0.277649 -0.317963 -0.36441
    0.166901 0.220856 0.144196
    -0.467896 0.15387 -0.345825
Cloud after filtering:
    -0.0164185 -0.177155 0.0244751
    0.166901 0.220856 0.144196

2.VoxelGrid Filter(体素化网格滤波):创建一个3D体素网格,每个体素中所有点将由质心来代替,将体素想象为立方体。

步骤:输入点云-创建滤波器对象-设置立方体大小-保存滤波后点云-可视化

头文件:#include <pcl/filters/voxel_grid.h>

代码:#include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>
#include <pcl/point_cloud.h>
#include<iostream>
#include <pcl/features/normal_3d.h>
using namespace std;
typedef pcl::PointXYZ PointT;

int main(int argc, char** argv)
{
	pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);			//待滤波点云
	///读入点云数据
	cout << "->正在读入点云..." << endl;
	/*pcl::io::loadPCDFile("rabbit.pcd", *cloud);*/
	pcl::PCDReader reader;
	reader.read("E:\\PCLNotes\\practice\\rabbit.pcd", *cloud);
	cout << "\t\t<读入点云信息>\n" << *cloud << endl;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);	//滤波后点云
	///体素滤波器点云下采样
	cout << "->正在体素下采样..." << endl;
	pcl::VoxelGrid<pcl::PointXYZ> vg;		//创建滤波器对象
	vg.setInputCloud(cloud);				//设置待滤波点云
	vg.setLeafSize(1.15f, 1.15f, 1.15f);	//设置体素大小
	vg.filter(*cloud_filtered);			//执行滤波,保存滤波结果于cloud_filtered

	///保存下采样点云
	cout << "->正在保存下采样点云..." << endl;
	pcl::PCDWriter writer;
	writer.write("sub.pcd", *cloud_filtered, true);
	cout << "\t\t<保存点云信息>\n" << *cloud_filtered << endl;
	/*return 0;
	}*/
	//================================= 滤波前后对比可视化 ================================= 

	/*pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("滤波前后对比"));*/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->initCameraParameters();//初始化相机参数
	/*-----视口1-----*/
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
	viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
	viewer->addText("befor_filtered", 10, 10, "v1_text", v1);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "befor_filtered_cloud", v1);

	/*-----视口2-----*/
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
	viewer->addText("after_filtered", 10, 10, "v2_text", v2);
	viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered, "after_filtered_cloud", v2);

	/*-----设置相关属性-----*/
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "befor_filtered_cloud", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "befor_filtered_cloud", v1);

	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "after_filtered_cloud", v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "after_filtered_cloud", v2);

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


	return 0;
}

执行结果:

问题:

 解决方法:https://blog.csdn.net/huhu7777/article/details/125358022

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值