CvBridge在ROS图像和OpenCV图像之间进行转化

2023-05-16

目录

1、概念

2、将ROS图像转化为OpenCV图像

3、将OpenCV图像转化为ROS图像消息

4、例子

1、概念

        ROS的 sensor_msgs/Image消息格式本身就是为了传递图像,但是因为因为不能直接传递给Opencv所以ROS提供了CvBridge来进行之间的转化。

         本文章将教您学会如何编写节点,使用CvBridge将ROS转化为OpenCV格式,还将学会如何将Opencv图像转化为ROS格式发布。

2、将ROS图像转化为OpenCV图像

         CvBridge定义了一个专门的CvImage类型,其中就包含了一个Opencv图像。CvImage包含的信息与 sensor_msgs/Image 包含的信息完全相同,CvImage类格式为:   

namespace cv_bridge {

class CvImage
{
public:
  std_msgs::Header header;//时间戳
  std::string encoding;//图像的格式
  cv::Mat image;//图像数据
};

typedef boost::shared_ptr<CvImage> CvImagePtr;
typedef boost::shared_ptr<CvImage const> CvImageConstPtr;

}

在ROS中我们有两个方式将sensor_msgs/Image转化为CvImage :

1、我们想修改数据,必须要复制消息

2、我们不想修改数据,我们可以安全的分享ROS消息数据,而不是复制

ROS提供以下转化为CvImage的函数:

// Case 1: Always copy, returning a mutable CvImage
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr& source,
                    const std::string& encoding = std::string());
CvImagePtr toCvCopy(const sensor_msgs::Image& source,
                    const std::string& encoding = std::string());

// Case 2: Share if possible, returning a const CvImage
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr& source,
                          const std::string& encoding = std::string());
CvImageConstPtr toCvShare(const sensor_msgs::Image& source,
                          const boost::shared_ptr<void const>& tracked_object,
                          const std::string& encoding = std::string());

 可以看出两种函数输入都是消息指针(订阅者的回调函数的参数),另一个参数为可选的编码参数。

1、toCvCopy返回的是ROS消息创建图像数据的副本,可以自由修改的 CvImagePtr。

2、toCvShare返回的是一个不可修改的CvImageConstPtr

图像编码的方式可以是以下几种:

  • 8UC[1-4]
  • 8SC[1-4]
  • 16UC[1-4]
  • 16SC[1-4]
  • 32SC[1-4]
  • 32FC[1-4]
  • 64FC[1-4]

 对于常用的编码方式给出几个例子:

   

  • mono8: CV_8UC1, 灰度图像

  • mono16: CV_16UC1, 16-bit 灰度图像

  • bgr8: CV_8UC3, 蓝绿红顺序彩色图像

  • rgb8: CV_8UC3, 红绿蓝顺序彩色图像

  • bgra8: CV_8UC4,  alpha 通道的BGR彩色图像

  • rgba8: CV_8UC4, alpha 通道的RGB彩色图像

注:mono8和bgr8是OpenCV最期望最常用的图像编码

3、将OpenCV图像转化为ROS图像消息

         要将CvImage转化为ROS图像消息,使用toImageMsg()成员函数:

class CvImage
{
  sensor_msgs::ImagePtr toImageMsg() const;

  //重载的函数
  void toImageMsg(sensor_msgs::Image& ros_image) const;
};

ROS为我们提供了两个重载,我们可以使用对象直接调用

4、例子

本实例第一个为官网例子,另一个笔者有时间加入一个使用自己摄像头的例子。

官网给出的例子是在图像转化为cv::Mat类型,并且在图像上绘制一个圆圈给OpenCV显示图像,并且还给ros重新发布图像。在你创建功能包依赖时需要加上(catkin_create_pkg)添加依赖:


sensor_msgs
cv_bridge
roscpp
std_msgs
image_transport  

头文件:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

 image_transport允许订阅压缩图像流。imgproc和hihgui为图像处理和gui也可以直接使用#include <opencv/opencv.hpp>包含所有opencv头文件。cv_bridge为本章的主题需要包含。接下来看定义的类和主函数。

static const std::string OPENCV_WINDOW = "Image window";

class ImageConverter
{
  ros::NodeHandle nh_;
  image_transport::ImageTransport it_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;

public:
  ImageConverter()
    : it_(nh_)
  {
    // Subscrive to input video feed and publish output video feed
    image_sub_ = it_.subscribe("/camera/image_raw", 1,
      &ImageConverter::imageCb, this);//订阅到图像则调用回调函数
    image_pub_ = it_.advertise("/image_converter/output_video", 1);发布话题

    cv::namedWindow(OPENCV_WINDOW);//设置窗口名
  }

  ~ImageConverter()
  {
    cv::destroyWindow(OPENCV_WINDOW);
  }

  void imageCb(const sensor_msgs::ImageConstPtr& msg)
  {
    cv_bridge::CvImagePtr cv_ptr;//接受到ros图像的对象
    try
    {
      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
    }
    catch (cv_bridge::Exception& e)
    {
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

    // Draw an example circle on the video stream
    //cv_ptr->image就是传递一个Mat类当opencv使用就可以了
    if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
      cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));

    // Update GUI Window
    cv::imshow(OPENCV_WINDOW, cv_ptr->image);
    cv::waitKey(3);

    // Output modified video stream
    image_pub_.publish(cv_ptr->toImageMsg());
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_converter");
  ImageConverter ic;
  ros::spin();
  return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CvBridge在ROS图像和OpenCV图像之间进行转化 的相关文章

  • CMake学习(3)—— 使用add_subdirectory()添加外部项目文件夹

    一般情况下 xff0c 我们的项目各个子项目都在一个总的项目根目录下 xff0c 但有的时候 xff0c 我们需要使用外部的文件夹 xff0c 怎么办呢 xff1f 例如 xff0c 在目录cxx utility example内的CMak
  • docker高级篇

    docker高级篇 一 dockerfile解析 1 dockerfile是什么 dockerfile是用来构建docker镜像的文本文件 xff0c 是有一条条构建镜像所需的指令和参数构成的脚本 2 dockerfile常用保留字指令 F
  • 死锁

    死锁 xff1a 死锁是指两个或两个以上的进程进在执行过程中 xff0c 由于资源竞争或由于相互通信而造成的一种阻塞式现象 xff0c 如果没有外力影响 那么它们将永远的持续下去 xff0c 此事称系统产生死锁现象 xff0c 这种永远互相
  • pygame入门教程-基础篇

    1 画布surface 我们先启动一个窗口 span class token keyword import span pygame pygame span class token punctuation span init span cla
  • LeetCode刷题(废弃)

    重要提示 xff1a 该博客不再更新 xff01 最新文章请参考LeetCode系列 xff01 为了更好地巩固算法知识 xff0c 打下扎实的计算机基础 好吧 xff0c 实在编不下去了 其实是闲着没事儿做 xff0c 不如动动脑 xff
  • 基于STM32的GPS模块驱动(AIR530)

    一 概述 由于做项目要用到GPS定位 xff0c 于是在某宝购买了这款GPS模块 项目采用的MCU是STM32 废话少说 xff0c 进入正题 二 GPS模块简介 Air530 模块是一款高性能 高集成度的多模卫星定位导航模块 体积小 功耗
  • UCOSIII中的任务调度和任务切换

    1 基本概念 任务调度的思想是 xff0c 几乎每时每刻让优先级别最高的就绪任务处于运行状态 xff0c 它由任务调度器来完成这个工作 xff08 任务级调度器OSShed 和中断级调度器OSIntExit xff09 任务切换 xff0c
  • 嵌入式开发者都该了解的10大算法

    算法一 xff1a 快速排序法 快速排序是由东尼 霍尔所发展的一种排序算法 在平均状况下 xff0c 排序 n 个项目要 n log n 次比较 在最坏状况下则需要 n2 次比较 xff0c 但这种状况并不常见 事实上 xff0c 快速排序
  • 蓝桥杯备赛——第八届省赛(模拟升降控制器)

    第八届省赛题目的控制逻辑相比之前更加复杂 xff0c 需要花一定的时间来理清逻辑 xff08 利用状态机 xff09 虽然之前对状态机有所了解 xff0c 但这是我第一次使用状态机 注 xff1a 1 PWM输出 xff1a PA6 TIM
  • C++实现http客户端连接服务端及客户端json数据的解析

    上一篇链接 xff1a https blog csdn net hfuu1504011020 article details 88785448 上一篇中说到Unicode转utf8格式的过程 xff0c 其中谈及到http以及json数据的
  • Linux版本 网络调试助手 发布

    Linux版本 网络调试助手 发布 Windows上有些小的调试助手软件使用起来很方便 xff0c Linux上也想用 还不如何自己写一个 xff0c 但是会写代码 xff0c 但并不会设计软件 那么就参考了一款Windows下的名字叫 T
  • No rule to make target错误解决方案

    报错 xff1a No rule to make target My Wall Paper2 img png needed by debug qrc resource cpp Stop 解决方案 xff1a 把 qrc文件删了新建一个res
  • C++难学吗?为什么难学?如何去学?

    C 43 43 难学吗 xff1f 为什么难学 xff1f 如何去学 xff1f 经常上网 xff0c 发现最多人问的问题就是C 43 43 难不难学 而得到的回答却基本上是说很难学 xff0c 甚至有说要两年才算入门 我开始是学VB的 x
  • 装 ros 报错 E: Unable to locate package ros-melodic-desktop-full

    换了清华源也不行 xff0c 后来发现有另一个安装方法 xff1a http wiki ros org ROS Installation TwoLineInstall wget c https raw githubusercontent c
  • ROS中map,odom坐标系的理解以及acml和robot_pose_ekf的对比和小车漂移方法解决

    之前一直不知道odom xff0c map到底是什么关系 xff0c 看了这个博客 xff1a https blog csdn net u012686154 article details 88174195 才了解了一些 这边记录我自己的看
  • 词根 -pose-,-posit- 表示“放置,站在那里,停在那里”

    pose n 姿势 姿态 v 使 摆好姿势 形成 引起 造成 vi 摆姿势 佯装 矫揉造作 poser n 装腔作势者 难题 compose v 组成 xff1b 作曲 xff1b 使镇定 xff08 com 一起 43 pose 放到一起
  • linux网络调试发包抓包工具

    目录 1 发包工具 1 1 sendip 1 2 tcpreply 2 抓包工具 2 1 tcpdump 2 2 tcpflow 3 速率测试工具 4 加密工具 4 1 tcpcryptd 5 linux网络编程 5 1 tcp 5 2 u
  • 飞行机器人(六)仿真平台- XTDrone Simulation Platform

    ubuntu18 04安装Ceres https www cnblogs com qilai p 13654810 html Installation Ceres Solver http ceres solver org installat
  • esp8266接入天猫精灵 实现控制家庭电灯

    之前 xff0c 我们看过很多关于Esp8266物联网开发的实例 现在很多家里照顾娃 xff0c 每天晚上都要去开灯给娃喂奶粉 家中有几个灯是用的小米的 xff0c 用米家APP可以控制 但有几个小夜灯不是物联网设备 xff0c 无法连接
  • 飞行机器人(七)仿真平台XTDrone + PX4编译

    0 编译PX4固件 参考仿真平台基础配置教程 xff08 中文详细教程 xff09 仿真平台基础配置 语雀 yuque com https www yuque com xtdrone manual cn basic config 按照教程

随机推荐