PCL | 直通滤波

该博客主要展示了如何使用PCL库对ROS中的sensor_msgs/PointCloud2消息进行滤波处理。通过实例化滤波器,如VoxelGrid和Passthrough,对点云数据进行降噪和裁剪,实现点云的预处理。代码中首先将ROS点云转换为PCL格式,然后应用滤波器,最后将滤波后的点云转换回ROS格式并发布。
摘要由CSDN通过智能技术生成
/***********************************************************
关于使用sensor_msgs/PointCloud2,
***********************************************************/

#include <ros/ros.h>
#include<iostream>
// PCL 的相关的头文件
#include <pcl/io/pcd_io.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/common/common.h>  

//滤波的头文件
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/statistical_outlier_removal.h>
using namespace std;
//申明发布器
ros::Publisher pub;
 //回调函数
void cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)  //特别注意的是这里面形参的数据格式
{
/*
-----------------------------------------------
 // 声明存储原始数据与滤波后的数据的点云的格式
  pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2;    //原始的点云的数据格式
  pcl::PCLPointCloud2ConstPtr cloudPtr(cloud); 
  pcl::PCLPointCloud2 cloud_filtered;     //存储滤波后的数据格式

  // 转化为PCL中的点云的数据格式
  pcl_conversions::toPCL(*input, *cloud);

  // 进行一个滤波处理
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;   //实例化滤波
  sor.setInputCloud (cloudPtr);     //设置输入的滤波
  sor.setLeafSize (0.9f, 0.9f, 0.9f);   //设置体素网格的大小
  sor.filter (cloud_filtered);      //存储滤波后的点云

  // 再将滤波后的点云的数据格式转换为ROS 下的数据格式发布出去
  sensor_msgs::PointCloud2 output;   //声明的输出的点云的格式
  pcl_conversions::fromPCL(cloud_filtered, output);    //第一个参数是输入,后面的是输出

  //发布命令
  pub.publish (output);
-----------------------------------------------
  */

	// PCL 第一代点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud_msg(new pcl::PointCloud<pcl::PointXYZ>); //pcl_cloud_msg要转化成的点云
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
	
	// ROS 点云 -> PCL 第一代点云
  cout << "->transforming point from ROS to pcl..." << endl;
	pcl::fromROSMsg(*input, *pcl_cloud_msg);

	//2.取得点云坐标极值
	pcl::PointXYZ minPt, maxPt;
	pcl::getMinMax3D(*pcl_cloud_msg, minPt, maxPt);
  cout << "minPt.x : " << minPt.x << " maxPt.x : " << maxPt.y << endl;
  cout << "minPt.y : " << minPt.x << " maxPt.y : " << maxPt.y << endl;
  cout << "minPt.z : " << minPt.x << " maxPt.z : " << maxPt.y << endl;

  // 原点云获取后进行滤波
  cout << "->filtering..." << endl;
  pcl::PassThrough<pcl::PointXYZ> pass;// 创建滤波器对象 直通滤波
  pass.setInputCloud (pcl_cloud_msg);//设置输入点云
  pass.setFilterFieldName ("z");//滤波字段名被设置为Z轴方向
  pass.setFilterLimits (-1.65, 0.5);//可接受的范围为(0.0,1.0) 
  //pass.setFilterLimitsNegative (true);//设置保留范围内 还是 过滤掉范围内
  pass.setFilterLimitsNegative (false);//设置保留范围内 还是 过滤掉范围内
  pass.filter (*cloud_filtered); //执行滤波,保存过滤结果在cloud_filtered

  // PCL 第一代点云-> ROS 点云 
  cout << "->transforming point from PCL to ROS..." << endl;
  sensor_msgs::PointCloud2 output;  // ROS 点云
  pcl::toROSMsg(*cloud_filtered, output);  // PCL 第一代点云 -> ROS 点云

  //发布命令
  cout << "->publishing ROS pointcloud2..." << endl;
  pub.publish (output);
}

int
main (int argc, char** argv)
{
  // 初始化 ROS节点
  ros::init (argc, argv, "filter_test_node");
  ros::NodeHandle nh;   //声明节点的名称

  // 为接受点云数据创建一个订阅节点
  ros::Subscriber sub = nh.subscribe ("/lidar_center/velodyne_points", 1, cloud_cb);

  //创建ROS的发布节点
  pub = nh.advertise<sensor_msgs::PointCloud2> ("output", 1);

  // 回调
  ros::spin ();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值