ROS与PCL环境中进行四种不同点云数据类型转换


前言

这篇文章是讲点云数据类型转换的,关于ROS和PCL中的点云数据类型可以看我上一篇文章介绍

下面这四种点云数据类型是 ROS 和 PCL 中最常用的点云数据结构,所有的转换主要围绕它们进行。

  1. sensor_msgs::PointCloud2:
  • ROS 中的标准点云消息类型。用于在 ROS 系统中发布和订阅点云数据。它具有灵活性,可以包含多个字段,因此适合表达复杂的点云数据。
  1. sensor_msgs::PointCloud:
  • ROS 中较老的点云消息类型。与 PointCloud2 相比,它的功能较为有限,通常用于表达较简单的点云数据。虽然现在使用较少,但仍在一些旧系统中存在。
  1. pcl::PointCloud<T>:
  • PCL 中的标准点云数据结构,其中 T 表示点的类型(如 pcl::PointXYZpcl::PointXYZRGB 等)。它在 PCL 中被广泛用于处理、操作和分析点云数据。
  1. pcl::PCLPointCloud2:
  • PCL 的通用点云数据结构,类似于 ROS 的 PointCloud2。它允许包含任意类型的点数据,但其主要用于在 PCL 内部处理时的通用数据格式。

这些类型之间的转换可以让你在 ROS 和 PCL 系统中灵活地处理点云数据。常见的转换路径包括:

  • ROS -> PCL:

    • sensor_msgs::PointCloud2 转换为 pcl::PointCloud<T>pcl::PCLPointCloud2

    • sensor_msgs::PointCloud 转换为 pcl::PointCloud<T>

  • PCL -> ROS:

    • pcl::PointCloud<T>pcl::PCLPointCloud2 转换为 sensor_msgs::PointCloud2

    • pcl::PointCloud<T> 转换为 sensor_msgs::PointCloud

通过这些转换,可以在 PCL 中处理点云数据后,再将其发布到 ROS 系统,或者将 ROS 系统中的点云数据引入到 PCL 中进行处理。


转换类型的点云数据主要是使用下面这些函数和方法

  • pcl_conversions::fromPCL
  • pcl_conversions::toPCL
  • pcl_conversions::moveFromPCL
  • pcl::fromPCLPointCloud2
  • pcl::toPCLPointCloud2
  • pcl::toROSMsg
  • pcl::fromROSMsg
  • convertPointCloudToPointCloud2
  • convertPointCloud2ToPointCloud

1. pcl_conversions::fromPCL

  • 作用:

    • pcl::PCLPointCloud2 类型转换为 sensor_msgs::PointCloud2 类型。
  • 使用场景:

    • 当你在 PCL (Point Cloud Library) 中处理点云数据并需要将其转换为 ROS 消息格式 (sensor_msgs::PointCloud2) 以便发布时使用。
  • 注意事项:

    • 需要确保输入的 pcl::PCLPointCloud2 数据结构有效并且包含所有必要的字段信息。
  • 优点:

    • 简化了 PCL 点云与 ROS 消息的转换。
  • 缺点:

    • 只适用于 pcl::PCLPointCloud2sensor_msgs::PointCloud2 之间的转换。
  • 使用示例:

#include <pcl_conversions/pcl_conversions.h>
#include <pcl/PCLPointCloud2.h>
#include <sensor_msgs/PointCloud2.h>

pcl::PCLPointCloud2 pcl_pc2;
sensor_msgs::PointCloud2 ros_pc2;

pcl_conversions::fromPCL(pcl_pc2, ros_pc2);

2. pcl_conversions::toPCL

  • 作用:

    • sensor_msgs::PointCloud2 类型转换为 pcl::PCLPointCloud2 类型。
  • 使用场景:

    • 当你从 ROS 订阅到 sensor_msgs::PointCloud2 消息并希望在 PCL 中处理该数据时使用。
  • 注意事项:

    • 确保 sensor_msgs::PointCloud2 消息是有效且兼容的。
  • 优点:

    • 使得 ROS 消息可以轻松地集成到 PCL 管道中进行处理。
  • 缺点:

    • 只适用于 sensor_msgs::PointCloud2pcl::PCLPointCloud2 之间的转换。
  • 使用示例:

#include <pcl_conversions/pcl_conversions.h>
#include <pcl/PCLPointCloud2.h>
#include <sensor_msgs/PointCloud2.h>

sensor_msgs::PointCloud2 ros_pc2;
pcl::PCLPointCloud2 pcl_pc2;

pcl_conversions::toPCL(ros_pc2, pcl_pc2);

3. pcl_conversions::moveFromPCL

  • 作用:

    • 类似于 fromPCL,但采用了移动语义以避免不必要的数据拷贝,将 pcl::PCLPointCloud2 转换为 sensor_msgs::PointCloud2
  • 使用场景:

    • 当需要优化性能并减少数据拷贝时使用。
  • 注意事项:

    • 由于使用了移动语义,pcl::PCLPointCloud2 对象在函数调用后将变为无效。
  • 优点:

    • 提高了转换过程中的性能。
  • 缺点:

    • 不能再访问转换后的 pcl::PCLPointCloud2 对象。
  • 使用示例:

#include <pcl_conversions/pcl_conversions.h>
#include <pcl/PCLPointCloud2.h>
#include <sensor_msgs/PointCloud2.h>

pcl::PCLPointCloud2 pcl_pc2;
sensor_msgs::PointCloud2 ros_pc2;

pcl_conversions::moveFromPCL(pcl_pc2, ros_pc2);

4. pcl::fromPCLPointCloud2

  • 作用:

    • pcl::PCLPointCloud2 类型转换为具体的 pcl::PointCloud<T> 类型,其中 T 是具体的点类型(如 pcl::PointXYZ)。
  • 使用场景:

    • 当你需要从 pcl::PCLPointCloud2 中提取具体类型的点云数据时使用。
  • 注意事项:

    • 确保 pcl::PCLPointCloud2 数据包含的字段与目标 pcl::PointCloud<T> 类型兼容。
  • 优点:

    • 允许将通用点云数据转换为特定的点类型,以便更容易访问和处理。
  • 缺点:

    • 如果数据类型不匹配,可能会丢失数据或导致错误。
  • 使用示例:

#include <pcl/conversions.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>

pcl::PCLPointCloud2 pcl_pc2;
pcl::PointCloud<pcl::PointXYZ> pcl_cloud;

pcl::fromPCLPointCloud2(pcl_pc2, pcl_cloud);

5. pcl::toPCLPointCloud2

  • 作用:

    • 将具体的 pcl::PointCloud<T> 类型转换为 pcl::PCLPointCloud2 类型,其中 T 是具体的点类型(如 pcl::PointXYZ)。
  • 使用场景:

    • 当你需要将特定点类型的点云数据转换为通用的 pcl::PCLPointCloud2 以进行通用处理或存储时使用。
  • 注意事项:

    • 确保点云数据与目标 pcl::PCLPointCloud2 格式兼容。
  • 优点:

    • 提供了一种方法来处理特定点类型数据并将其转换为通用格式。
  • 缺点:

    • 如果数据结构不匹配,可能会导致数据丢失或错误。
  • 使用示例:

#include <pcl/conversions.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>

pcl::PointCloud<pcl::PointXYZ> pcl_cloud;
pcl::PCLPointCloud2 pcl_pc2;

pcl::toPCLPointCloud2(pcl_cloud, pcl_pc2);

6. pcl::toROSMsg

  • 作用:

    • pcl::PointCloud<T> 类型转换为 sensor_msgs::PointCloud2 类型,以便在 ROS 中发布。
  • 使用场景:

    • 当你在 PCL 中处理点云数据并需要将其转换为 ROS 消息格式时使用。
  • 注意事项:

    • 确保输入的点云数据类型与目标 ROS 消息格式兼容。
  • 优点:

    • 简化了 PCL 点云与 ROS 消息的转换。
  • 缺点:

    • 只适用于 pcl::PointCloud<T>sensor_msgs::PointCloud2 之间的转换。
  • 使用示例:

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>

pcl::PointCloud<pcl::PointXYZ> pcl_cloud;
sensor_msgs::PointCloud2 ros_pc2;

pcl::toROSMsg(pcl_cloud, ros_pc2);

7. pcl::fromROSMsg

  • 作用:

    • sensor_msgs::PointCloud2 类型转换为 pcl::PointCloud<T> 类型,其中 T 是具体的点类型(如 pcl::PointXYZ)。
  • 使用场景:

    • 当你从 ROS 订阅 sensor_msgs::PointCloud2 消息并需要在 PCL 中处理该数据时使用。
  • 注意事项:

    • 确保输入的 ROS 消息与目标 PCL 点类型兼容。
  • 优点:

    • 使得 ROS 消息可以轻松地集成到 PCL 管道中进行处理。
  • 缺点:

    • 只适用于 sensor_msgs::PointCloud2pcl::PointCloud<T> 之间的转换。
  • 使用示例:

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include <sensor_msgs/PointCloud2.h>

sensor_msgs::PointCloud2 ros_pc2;
pcl::PointCloud<pcl::PointXYZ> pcl_cloud;

pcl::fromROSMsg(ros_pc2, pcl_cloud);

8. convertPointCloudToPointCloud2

  • 作用:

    • sensor_msgs::PointCloud 转换为 sensor_msgs::PointCloud2 类型。
  • 使用场景:

    • 当需要将较老的 PointCloud 数据格式转换为较新的 PointCloud2 数据格式以便与现代系统或工具兼容时使用。
  • 注意事项:

    • 需要确保所有点和通道数据都被正确地转换和保留。
  • 优点:

    • 方便将旧格式的数据转换为新格式。
  • 缺点:

    • 在某些情况下,PointCloud 数据可能不包含足够的信息来完全利用 PointCloud2 的所有特性。
  • 使用示例:

#include "sensor_msgs/point_cloud_conversion.h"
#include "sensor_msgs/PointCloud.h"
#include "sensor_msgs/PointCloud2.h"

sensor_msgs::PointCloud pc_msg;
sensor_msgs::PointCloud2 pc2_msg;

bool success = convertPointCloudToPointCloud2(pc_msg, pc2_msg);
if (success) {
    ROS_INFO("Conversion successful");
} else {
    ROS_ERROR("Conversion failed");
}

9. convertPointCloud2ToPointCloud

  • 作用:

    • sensor_msgs::PointCloud2 转换为 sensor_msgs::PointCloud 类型。
  • 使用场景:

    • 当需要将较现代的 PointCloud2 数据格式转换为较旧的 PointCloud 数据格式以与旧的工具或系统兼容时使用。
  • 注意事项:

    • 转换时需要确保 PointCloud2 数据中的所有字段能够正确映射到 PointCloud 类型中。

    • PointCloud2 中的字段可能会丢失,如果 PointCloud 无法直接表示这些字段(例如一些自定义的通道数据)。

  • 优点:

    • 提供了现成的转换工具,简化了开发。
  • 缺点:

    • 某些复杂的字段可能无法被完全保留。
  • 使用示例:

#include "sensor_msgs/point_cloud_conversion.h"
#include "sensor_msgs/PointCloud2.h"
#include "sensor_msgs/PointCloud.h"

sensor_msgs::PointCloud2 pc2_msg;
sensor_msgs::PointCloud pc_msg;

bool success = convertPointCloud2ToPointCloud(pc2_msg, pc_msg);
if (success) {
    ROS_INFO("Conversion successful");
} else {
    ROS_ERROR("Conversion failed");
}
  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ROS,可以使用PointCloud2消息类型来表示点云数据。要将PCL点云转换为ROS点云,可以按照以下步骤操作: 1. 创建一个PointCloud2消息对象,设置其header和fields属性。Header属性包含一些元数据,如时间戳、坐标系等,而Fields属性定义了每个点的数据类型和名称。 2. 将PCL点云数据转换为一个ROS消息的二进制数据数组。这可以通过将PCL点云数据复制到ROS消息的二进制数据数组来完成。 3. 将二进制数据数组设置为PointCloud2消息对象的data属性。 4. 将PointCloud2消息对象发布到ROS话题,以便其他节点可以接收和处理该点云数据。 下面是一个示例代码,可以将一个PCL点云转换为ROS点云并发布到ROS话题: ``` #include <ros/ros.h> #include <pcl_conversions/pcl_conversions.h> #include <sensor_msgs/PointCloud2.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> int main(int argc, char **argv) { // 初始化ROS节点 ros::init(argc, argv, "pcl_to_ros_node"); ros::NodeHandle nh; // 创建一个PCL点云对象 pcl::PointCloud<pcl::PointXYZ> pcl_cloud; // 填充点云数据(省略) // 创建一个ROS消息对象 sensor_msgs::PointCloud2 ros_cloud; // 将PCL点云数据转换为ROS消息的二进制数据数组 pcl::toROSMsg(pcl_cloud, ros_cloud); // 设置ROS消息对象的header和fields属性 ros_cloud.header.frame_id = "pcl_frame"; ros_cloud.header.stamp = ros::Time::now(); ros_cloud.fields.resize(3); ros_cloud.fields[0].name = "x"; ros_cloud.fields[0].offset = 0; ros_cloud.fields[0].datatype = sensor_msgs::PointField::FLOAT32; ros_cloud.fields[0].count = 1; ros_cloud.fields[1].name = "y"; ros_cloud.fields[1].offset = 4; ros_cloud.fields[1].datatype = sensor_msgs::PointField::FLOAT32; ros_cloud.fields[1].count = 1; ros_cloud.fields[2].name = "z"; ros_cloud.fields[2].offset = 8; ros_cloud.fields[2].datatype = sensor_msgs::PointField::FLOAT32; ros_cloud.fields[2].count = 1; // 设置ROS消息对象的data属性 ros_cloud.data = std::vector<uint8_t>(ros_cloud.point_step * pcl_cloud.size()); memcpy(&ros_cloud.data[0], pcl_cloud.points.data(), ros_cloud.data.size()); // 创建一个ROS话题发布者,并发布ROS消息对象 ros::Publisher pub = nh.advertise<sensor_msgs::PointCloud2>("ros_cloud_topic", 1); pub.publish(ros_cloud); // 进入ROS循环 ros::spin(); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沮丧的迈克尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值