PCL中点云数据格式之间的转化
(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中点云数据格式之间的转化的更多相关文章
- pcl点云文件格式
PCD版本 在点云库(PCL)1.0版本发布之前,PCD文件格式有不同的修订号.这些修订号用PCD_Vx来编号(例如,PCD_V5.PCD_V6.PCD_V7等等),代表PCD文件的0.x版本号.然而 ...
- PCL点云库:ICP算法
ICP(Iterative Closest Point迭代最近点)算法是一种点集对点集配准方法.在VTK.PCL.MRPT.MeshLab等C++库或软件中都有实现,可以参见维基百科中的ICP Alg ...
- PCL学习之:将超声数据按照PCL点云方式发布出去
前言:基于2D激光雷达的机器人,想让它跑自动导航,众所周知有2个比较明显的缺陷,1,那就是普通的激光雷达无法对玻璃或是镜面物体有反映; 2,机器人避障时只能对某一个平面的物体有反映,超过或者低于这个平 ...
- javascript中日期格式与时间戳之间的转化
日期格式与时间戳之间的转化 一:日期格式转化为时间戳 function timeTodate(date) { var new_str = date.replace(/:/g,'-'); new_str ...
- C#入门篇6-6:字符串操作 StringBiulder string char[]之间的转化
//StringBiulder string char[]之间的转化 public static void Fun3() { StringBuilder sb = new StringBuilder( ...
- Android中Bitmap, Drawable, Byte,ID之间的转化
Android中Bitmap, Drawable, Byte,ID之间的转化 1. Bitmap 转化为 byte ByteArrayOutputStream out = new ByteArray ...
- NSJSONSerialization-JSON数据与NSDictionary和NSArray之间的转化
转载▼ 在iOS 5 中,苹果引入了一个解析JSON串的NSJSONSerialization类. 通过该类,我们可以完成JSON数据与NSDictionary和NSArray之间的转化. ...
- 浅析mysql 共享表空间与独享表空间以及他们之间的转化
innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.什么是共享表空间和独占表空间共 ...
- String和数字之间的转化
主要是JDK的代码,还是比较的经典,值得一看,例如: package alg; /** * @author zha 字符串之间的转化 */ public class Alg3StringToint { ...
随机推荐
- IOS7 新特性
相关ios7新特性 帖子.挺全的.一定要看看哪 http://www.devdiv.com/iOS_iPhone-ios_ui_uikit_text_kit_-thread-203631-1-1.ht ...
- linux c select函数使用求解释
代码非常easy,就是发送c语言发送http请求.但 i= read(sockfd, buf, BUFSIZE-1); 能够正常执行, 替换为i= Read(sockfd, buf, B ...
- 关于JAVA的参数列表传值的问题
java传参和C++传指针不一样.它不能传入一个参数,再用这个参数去new一个新的object,再调用者看来,这没用. java中传的参数是stack上复制的值,如果传的是object,那么传的是该o ...
- tomcat启动窗口中的时间与系统时间不一致
比我的系统时间慢8个小时,应该如何设置? 产生原因是因为Tomcat中的时区设置与操作系统的时区设置不一致,通过修改Tomcat根目录下的bin文件夹中的catalina.bat文件,增加以下配置解决 ...
- Ultraedit使用小技巧
4. 编辑文件如何加入时间戳 ?F7 快捷键即可.你试试看? 5. 为何拷贝(Copy)/粘贴(Paste)功能不能用了?不怕大家笑话,我有几次使用 UltraEdit的过程中发现拷贝与粘贴的内容是不 ...
- 【Unity】12.1 基本概念
开发环境:Win10.Unity5.3.4.C#.VS2015 创建日期:2016-05-09 一.简介 导航网格(Navmesh)是世界坐标系中几何体的简化表示,被游戏代理用来进行全局导航.通常,代 ...
- python 给文件批量加‘“’ ”,"
file = open('face.txt','r') filew = open('face1.txt','w') try: for line in file: print(line) if line ...
- IOC的实现原理—反射与工厂模式的结合
反射机制概念 我们考虑一个场景,如果我们在程序运行时,一个对象想要检视自己所拥有的成员属性,该如何操作?再考虑另一个场景,如果我们想要在运行期获得某个类的Class信息如它的属性.构造方法.一般方 ...
- socket.io笔记一
//服务端代码 var server = require('http').createServer(app); var io = require('socket.io')(server,{path:' ...
- java二维数组遍历
数组名加上length(arr.length),表示该数组的行数(Row): 指定索引加上length(arr[x].length),表示该行的元素个数,即该行的列数(Column). public ...