PCL中点云数据格式之间的转化

摘要:
(1) 关于pcl::PCLPointCloud2::Ptr和pcl::PointCloud中的数据结构之间的差异pcl:::PointXYZ::PointXYZ(float_x,float_y,float_xz):structPCLPointCloud2{PCLPointCloud3():header(),height(0),width(0)、fields(),is_bi

(1) 关于pcl::PCLPointCloud2::Ptr和pcl::PointCloud<pcl::PointXYZ>两中数据结构的区别

pcl::PointXYZ::PointXYZ ( float_x,
                  float_y,
                  float_z
                    ) 

区别:    

 struct PCLPointCloud2
 {
  PCLPointCloud2 () : header (), height (0), width (0), fields (),
 is_bigendian (false), point_step (0), row_step (0),
  data (), is_dense (false)
  {
 #if defined(BOOST_BIG_ENDIAN)
  is_bigendian = true;
 #elif defined(BOOST_LITTLE_ENDIAN)
  is_bigendian = false;
 #else
 #error "unable to determine system endianness"
 #endif
  }
 
  ::pcl::PCLHeader header;
 
  pcl::uint32_t height;
  pcl::uint32_t width;
 
  std::vector< ::pcl::PCLPointField> fields;
 
  pcl::uint8_t is_bigendian;
  pcl::uint32_t point_step;
  pcl::uint32_t row_step;
 
  std::vector<pcl::uint8_t> data;
 
  pcl::uint8_t is_dense;
 
  public:
  typedef boost::shared_ptr< ::pcl::PCLPointCloud2> Ptr;
  typedef boost::shared_ptr< ::pcl::PCLPointCloud2 const> ConstPtr;
  }; // struct PCLPointCloud2

那么要实现它们之间的数据转换,

举个例子

 pcl::PCLPointCloud2::Ptr cloud_blob (new pcl::PCLPointCloud2), cloud_filtered_blob (new pcl::PCLPointCloud2);//申明滤波前后的点云
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>), cloud_p (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);

  // 读取PCD文件
  pcl::PCDReader reader;
  reader.read ("table_scene_lms400.pcd", *cloud_blob);
   //统计滤波前的点云个数
  std::cerr << "PointCloud before filtering: " << cloud_blob->width * cloud_blob->height << " data points." << std::endl;

  // 创建体素栅格下采样: 下采样的大小为1cm
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;  //体素栅格下采样对象
  sor.setInputCloud (cloud_blob);             //原始点云
  sor.setLeafSize (0.01f, 0.01f, 0.01f);    // 设置采样体素大小
  sor.filter (*cloud_filtered_blob);        //保存

  // 转换为模板点云
  pcl::fromPCLPointCloud2 (*cloud_filtered_blob, *cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points." << std::endl;

  // 保存下采样后的点云
  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("table_scene_lms400_downsampled.pcd", *cloud_filtered, false);

程序中红色部分就是一句实现两者之间的数据转化的我们可以看出

cloud_filtered_blob 声明的数据格式为pcl::PCLPointCloud2::Ptr  cloud_filtered_blob (new pcl::PCLPointCloud2);
cloud_filtered 申明的数据格式  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>)

那么依照这种的命名风格我们可以查看到更多的关于的数据格式之间的转换的类的成员

(1)

   void pcl::fromPCLPointCloud(const pcl:PCLPointCloud2 & msg

                                                   pcl::PointCloud<PointT>  & cloud

                                                     const MsgFieldMap & filed_map

                                                     )

函数使用field_map实现将一个pcl::pointcloud2二进制数据blob到PCL::PointCloud<pointT>对象

使用 PCLPointCloud2 (PCLPointCloud2, PointCloud<T>)生成自己的 MsgFieldMap

MsgFieldMap field_map;
createMapping<PointT> (msg.fields, field_map);

(2)

void pcl::fromPCLPointCloud2(const pcl::PCLPointCloud & msg

                                                  pcl::PointCloud<pointT> &cloud

                                                  )

把pcl::PCLPointCloud数据格式的点云转化为pcl::PointCloud<pointT>格式

(3)

 void pcl::fromROSMsg(const pcl:PCLPointCloud2 & msg

                                 pcl::PointCloud<PointT>  & cloud

                                  const MsgFieldMap & filed_map

                                     )

(4)

 void pcl::fromROSMsg(const pcl:PCLPointCloud2 & msg

                                  pcl::PointCloud<PointT>  & cloud

                                     )

在使用fromROSMsg是一种在ROS 下的一种数据转化的作用,我们举个例子实现订阅使用kinect发布   /camera/depth/points  从程序中我们可以看到如何使用该函数实现数据的转换。并且我在程序中添加了如果使用PCL的库实现在ROS下调用并且可视化,

/************************************************
关于如何使用PCL在ROS 中,实现简单的数据转化
时间:2017.3.31

****************************************************/


#include <ros/ros.h>
// PCL specific includes
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>

#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/cloud_viewer.h>

ros::Publisher pub;
  

  pcl::visualization::CloudViewer viewer("Cloud Viewer");

void 
cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
{
 // 创建一个输出的数据格式
  sensor_msgs::PointCloud2 output;  //ROS中点云的数据格式
  //对数据进行处理
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);

  output = *input;

    pcl::fromROSMsg(output,*cloud);

    
     //blocks until the cloud is actually rendered
    viewer.showCloud(cloud);
    

  pub.publish (output);
}



int
main (int argc, char** argv)
{ 


  // Initialize ROS
  ros::init (argc, argv, "my_pcl_tutorial");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  ros::Subscriber sub = nh.subscribe ("input", 1, cloud_cb);
   ros::Rate loop_rate(100);
  // Create a ROS publisher for the output point cloud
  pub = nh.advertise<sensor_msgs::PointCloud2> ("output", 1);
    

  

  // Spin
  ros::spin ();
/*
while (!viewer.wasStopped ())
    {

    } 
*/

 
}

那么对于这一段小程序实现了从发布的节点中转化为可以使用PCL的可视化函数实现可视化,并不一定要用RVIZ来实现,所以我们分析以下其中的步骤,在订阅话题的回调函数中,

void  cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)        //这里面设置了一个数据类型为sensor_msgs::PointCloud2ConstPtr& input形参
{
  sensor_msgs::PointCloud2 output;                                //ROS中点云的数据格式(或者说是发布话题点云的数据类型)
  pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);     //对数据转换后存储的类型
  output = *input;
   pcl::fromROSMsg(output,*cloud);   //最重要的一步骤实现从ROS到PCL中的数据的转化,同时也可以直接使用PCL库实现可视化

  viewer.showCloud(cloud);  //PCL库的可视化
  pub.publish (output);     //那么原来的output的类型仍然是sensor_msgs::PointCloud2,可以通过RVIZ来可视化
}

那么也可以使用

  pcl::PCDWriter writer;
  writer.write<pcl::PointXYZ> ("ros_to_PCL.pcd", *cloud, false);

这一段代码来实现保存的作用。那么见到那看一下可视化的结果

PCL中点云数据格式之间的转化第1张

使用pcl_viewer 可视化保存的PCD文件

PCL中点云数据格式之间的转化第2张

于2018年5月5号看到再次更新一点小笔记,比如我们在写程序的过程中经常会遇到定义点云的数据格式为

typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
PointCloudT::Ptr cloud_;

但是我们在运行一个简单的例程比如直通滤波器的内容是一般的点云的定义为

typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloudT

PointCloudT::Ptr cloud (new PointCloudT);
PointCloudT::Ptr cloud_filtered (new PointCloudT)

  pcl::PassThrough<PointT> pass;
  pass.setInputCloud (cloud);            //设置输入点云
  pass.setFilterFieldName ("z");         //设置过滤时所需要点云类型的Z字段
  pass.setFilterLimits (0.0, 1.0);        //设置在过滤字段的范围
  //pass.setFilterLimitsNegative (true);   //设置保留范围内还是过滤掉范围内
  pass.filter (*cloud_filtered);            //执行滤波,保存过滤结果在cloud_filtered

对比我们可以看出

这里两种定义的方法的不同是不能在直通滤波器直接使用的

PointCloudT::Ptr   cloud_;
PointCloudY::Ptr   cloud_tmp(new PointCloudT)

如何去转换呢?

如下:

pcl::copyPointCloud (*cloud_tmp, *cloud_);

在构造上的区别:常规变量定义不使用new,定义的对象在定义后就自动可以使用,指针变量定义必须使用new进行对象实例的构造。

使用上的区别:使用new的是一个指针对象,此时对对象成员的访问需要使用指针操作符“->”,而不使用new的是常规对象,使用普通成员操作符“.”。

可能写的比较乱,但是有用到关于PCL中点云数据类型的转换以及可视化等功能可以参考,同时欢迎有兴趣者扫描下方二维码或者QQ群

与我交流并且投稿,大家一起学习,共同进步与分享

PCL中点云数据格式之间的转化第3张  PCL中点云数据格式之间的转化第4张

免责声明:文章转载自《PCL中点云数据格式之间的转化》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【支付宝】"验签出错,sign值与sign_type参数指定的签名类型不一致:sign_type参数值为RSA,您实际用的签名类型可能是RSA2"部署 Graylog 日志系统下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ROS入门笔记(六):ROS系统架构

ROS入门笔记(六): ROS系统架构 1 ROS系统架构    1.1 文件系统(重点)    1.2 计算图    1.3 开源社区 1 ROS系统架构   1.1 文件系统(重点) 文件系统:主要指在硬盘里能看到的ROS目录和文件:   1)元功能包(Meta Packages):组织多个用于同一目的功能包。2)元功能包清单(Meta...

ROS学习之日志消息

ROS学习之日志消息 ROS日志系统的核心思想,就是使程序生成一些简短的文本字符流,这些字符流便是日志消息。 0.1严重级别        ROS中,日志消息分为五个不同的严重级别,也可简称为严重性或者级别。按照严重性程度递增,这些级别有       DEBUG       INFO       WARN       ERROR       FATAL 0...

UML建模三个工具: StarUML ,Telelogic TAU 和 Rose

UML建模软件目前用的主要有3种: 商业版本:Telelogic TAU 和 RationalRose开源版本:StarUML Telelogic TAU与Rational Rose的功能很强,但是需要买License。 StarUML就是希望能提供和TAU/Rose一样功能的开源版本。 目前使用起来还是不错的。 能熟练使用其中一个是软件设计人员的基本功...

ROS-节点参数param

ROS中有如下3种获取参数的方式。 在launch中写 <param name="debug_imu"  value="true">     不管是上面何种数据类型都要带引号 #include "ros/ros.h" #include <cstdlib> using namespace std; int main(int...

关于ROS(Robot OS 机器人操作系统)

关于ROS(Robot OS 机器人操作系统) 对于ROS的安装,在它的官方网站: http://wiki.ros.org/ROS/Installation 中也有详细说明。但是对于像博主这样先天英语发育不全的人来说,直接看官网还是有点困难的。 所以博主痛定思痛,经过一番呕心沥血与含辛茹苦的调研后(其实就是看了几篇相关博客),终于在博主的电脑上成功安装了R...

Cause: java.lang.UnsupportedOperationException

运行web项目的时候出现以下错误: ### Cause: java.lang.UnsupportedOperationException    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.ja...