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 { ...
随机推荐
- MySQL 5.6学习笔记(查询数据、插入、更新、删除数据)
1. 查询语法 SELECT {*|<字段列表>} [FROM table_references [WHERE where_condition] [GROUP BY {col_name | ...
- android Ant 打包
1.首先我们先看看android 中SDK的${sdk.dir}/tools/ant/build.xml 这个build其实已经把Eclipse的开发操作已经全部实现了. 2.我们现在打包只需要把自己 ...
- jQuery CSS()方法改变CSS样式实例解析
转自:http://www.jbxue.com/article/24588.html 分享一个jQuery入门实例:使用CSS()方法改变现有的CSS样式表,css()方法在使用上具有多样性.其中有一 ...
- 【Unity】3.1 利用内置的3D对象创建三维模型
分类:Unity.C#.VS2015 创建日期:2016-04-02 一.基本概念 Unity已经内置了一些基本的3D对象,利用这些内置的3D对象就可以直接构建出各种3D模型(当然,复杂的三维模型还需 ...
- PxCook(像素大厨)
PxCook(像素大厨)是一款切图设计工具软件.自2.0.0版本开始,支持PSD文件的文字,颜色,距离自动智能识别. 优点在于将标注.切图这两项设计完稿后集成在一个软件内完成,支持Windows和Ma ...
- 菜鸟学Java(九)——Servlet的基本配置
学习JavaWeb的人没有不知道Servlet的吧,而要用Servlet就需要在web.xml中进行配置.相信有很多初学者跟我当初一样,对于一些配置参数不是很理解,今天就说说Servlet最基本的配置 ...
- mongodb学习比较(数据操作篇)
1. 批量插入: 以数组的方式一次插入多个文档可以在单次TCP请求中完成,避免了多次请求中的额外开销.就数据传输量而言,批量插入的数据中仅包含一份消息头,而多次单条插入则会在每次插入数据时封 ...
- 技术范儿的 Keep 发力AI赛道,为什么“虚拟教练”会更懂你?
http://www.tmtpost.com/3363367.html 摘要: 虚拟教练技术会整合到一些业务场景和硬件产品中收费,但是收费的具体情况彭跃辉还暂未透露. 图片来源于Unsplash 自去 ...
- 开发openfire 消息拦截器插件PacketInterceptor
开发消息拦截器的步骤跟开发简单插件步骤一样,要开发消息拦截器插件,首先继承PacketInterceptor包拦截类,然后在initializelPlugin()方法中注册拦截器,就可以实现inter ...
- LeetCode: Binary Tree Maximum Path Sum 解题报告
Binary Tree Maximum Path SumGiven a binary tree, find the maximum path sum. The path may start and e ...