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

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

区别:

 struct PCLPointCloud2
{
PCLPointCloud2 () : header (), height (), width (), fields (),
is_bigendian (false), point_step (), row_step (),
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", , cloud_cb);
ros::Rate loop_rate();
// Create a ROS publisher for the output point cloud
pub = nh.advertise<sensor_msgs::PointCloud2> ("output", ); // 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_viewer 可视化保存的PCD文件

于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中点云数据格式之间的转化的更多相关文章

  1. pcl点云文件格式

    PCD版本 在点云库(PCL)1.0版本发布之前,PCD文件格式有不同的修订号.这些修订号用PCD_Vx来编号(例如,PCD_V5.PCD_V6.PCD_V7等等),代表PCD文件的0.x版本号.然而 ...

  2. PCL点云库:ICP算法

    ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法.在VTK.PCL.MRPT.MeshLab等C++库或软件中都有实现,可以参见维基百科中的ICP Alg ...

  3. PCL学习之:将超声数据按照PCL点云方式发布出去

    前言:基于2D激光雷达的机器人,想让它跑自动导航,众所周知有2个比较明显的缺陷,1,那就是普通的激光雷达无法对玻璃或是镜面物体有反映; 2,机器人避障时只能对某一个平面的物体有反映,超过或者低于这个平 ...

  4. javascript中日期格式与时间戳之间的转化

    日期格式与时间戳之间的转化 一:日期格式转化为时间戳 function timeTodate(date) { var new_str = date.replace(/:/g,'-'); new_str ...

  5. C#入门篇6-6:字符串操作 StringBiulder string char[]之间的转化

    //StringBiulder string char[]之间的转化 public static void Fun3() { StringBuilder sb = new StringBuilder( ...

  6. Android中Bitmap, Drawable, Byte,ID之间的转化

    Android中Bitmap, Drawable, Byte,ID之间的转化 1.  Bitmap 转化为 byte ByteArrayOutputStream out = new ByteArray ...

  7. NSJSONSerialization-JSON数据与NSDictionary和NSArray之间的转化

    转载▼     在iOS  5 中,苹果引入了一个解析JSON串的NSJSONSerialization类. 通过该类,我们可以完成JSON数据与NSDictionary和NSArray之间的转化. ...

  8. 浅析mysql 共享表空间与独享表空间以及他们之间的转化

        innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.什么是共享表空间和独占表空间共 ...

  9. String和数字之间的转化

    主要是JDK的代码,还是比较的经典,值得一看,例如: package alg; /** * @author zha 字符串之间的转化 */ public class Alg3StringToint { ...

随机推荐

  1. 【python】Python 资源大全中文版

    申明:感谢原作者的整理与分享,本篇文章分享自:https://www.jianshu.com/p/9c6ae64a1bd7 GitHub 上有一个 Awesome - XXX 系列的资源整理,资源非常 ...

  2. linux分享一:网络设置

    在Linux中,TCP/IP网络的配置信息存在几个不同的文件里面,这些文件分别就是 /etc/sysconfig/network. 网卡配置文件. /etc/hostc. /ect/resolv.co ...

  3. [转载]java日志框架log4j详细配置及与slf4j联合使用教程

    一.log4j基本用法 首先,配置log4j的jar,maven工程配置以下依赖,非maven工程从maven仓库下载jar添加到“build path” 1 2 3 4 5 <dependen ...

  4. 【Unity】7.4 游戏外设输入

    分类:Unity.C#.VS2015 创建日期:2016-04-21 一.简介 Unity可以处理摇杆.游戏手柄.方向盘等标准游戏外设的输入,使用的方法如下图所示: 虚拟按键需要在输入管理器中配置,把 ...

  5. 【iOS XMPP】使用XMPPFramewok(一):添加XMPPFramework(XCode 4.6.2)

    转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/09/3069145.html XMPPFramework GitHub: https://g ...

  6. ubuntu svn rabbitvcs 安装

    参考链接:http://blog.csdn.net/weng_xianhu/article/details/10079179 32位系统完全按照上面链接安装没有问题,但是如果是64位系统,第六步下载资 ...

  7. # tail -f /var/log/zabbix/zabbix_agentd.log sudo: sorry, you must have a tty to run sudo

    /etc/sudoers 1)Defaults requiretty,修改为 #Defaults requiretty,表示不需要控制终端. 2)Defaults requiretty,修改为 Def ...

  8. django_simple_captcha使用笔记

    一.先来官方文档的步骤: Install django-simple-captcha via pip: pip install  django-simple-captcha Add captcha t ...

  9. Burpsuite如何抓取使用了SSL或TLS传输的 IOS App流量

    之前一篇文章介绍了Burpsuite如何抓取使用了SSL或TLS传输的Android App流量,那么IOS中APP如何抓取HTTPS流量呢, 套路基本上与android相同,唯一不同的是将证书导入i ...

  10. Python 传值和传址 copy/deepcopy

    传值:被调函数局部变量改变不会影响主调函数局部变量 传址:被调函数局部变量改变会影响主调函数局部变量 Python参数传递方式:传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值:如 ...