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

这篇具有很好参考价值的文章主要介绍了CvBridge在ROS图像和OpenCV图像之间进行转化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、概念

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

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

4、例子

1、概念

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

cv_bridge::cvimageptr,ros,图像处理,c++,linux,计算机视觉

         本文章将教您学会如何编写节点,使用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;
}

5 自己的Mat类转为ros图像

        这里官方的cvImage是通过msg进行初始化的,那我一开始将就只有Mat类的图像如何操作。笔者想定义一个cvImage然后用cv_ptr->image=Mat就不可以了吗?

v_bridge::CvImagePtr ptr;
ptr.image=image.clone();

很遗憾这样是不行的,因为这个对象调用的初始构造函数。通过阅读官方源码,可以看出cvImage的构造方式:

CvImage() {}

  /**
   * \brief Constructor.
   */
  CvImage(
    const std_msgs::msg::Header & header, const std::string & encoding,
    const cv::Mat & image = cv::Mat())
  : header(header), encoding(encoding), image(image)
  {
  }

如果我们单纯之创建一个cvImage对象不正确的完成它的初始化就无法正常使用这个对象。正确的方式:

sensor_msgs::ImagePtr  msg = cv_bridge::CvImage(std_msgs::Header(), "mono8", Right_raw).toImageMsg();

ok,这样就可以正常发布我们的图像了。 文章来源地址https://www.toymoban.com/news/detail-620202.html

到了这里,关于CvBridge在ROS图像和OpenCV图像之间进行转化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ubuntu18、20 cv_bridge 与自带opencv版本冲突问题

    背景: nvidia tx2、xvaier 装机自带 ubuntu18 + opencv4  后来我们会安装melodic的ros,ros中的cv_bridge 默认cv版本是3.2.0 编译带cv_bridge的代码时,会报错会崩溃,因为版本冲突了 为了解决该问题, 行之有效的一种解法是重新安装 cv_bridge,使其兼容opencv 4 安装cv_bridge with opencv4 1、git clo

    2024年02月07日
    浏览(47)
  • ubuntu20.04安装opencv 3.2.0以及cv_bridge踩坑记录

    本次安装是在我的双系统下安装的,不同ubuntu版本或者不同硬件平台情况也许会有所不同,仅供参考。 第一步: 我采用的是github官方代码仓库下载安装的方式,下载的是3.2.0版本(其余版本安装过程类似) opencv官方链接 第二步:安装依赖项 值得一提的是,在此处我遇到过

    2024年02月04日
    浏览(59)
  • 看这篇就够了——opencv与libopencv与cv_bridge的安装与使用

      OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉处理开源软件库,是由Intel公司俄罗斯团队发起并参与和维护,支持与计算机视觉和机器学习相关的众多算法。OpenCV基于C++实现,同时提供python, Ruby, Matlab等语言的接口。OpenCV-Python是OpenCV的Python API,结合

    2024年02月03日
    浏览(46)
  • “Python OpenCV 图像格式转换:RGB与BGR互转“——使用OpenCV库进行图像处理的过程中,经常需要进行不同格式之间的转换。其中最为常见的就是R...

    “Python OpenCV 图像格式转换:RGB与BGR互转”——使用OpenCV库进行图像处理的过程中,经常需要进行不同格式之间的转换。其中最为常见的就是RGB和BGR格式之间的转换。本文将详细介绍如何使用opencv-python库将图像从RGB格式转换为BGR格式以及从BGR格式转换为RGB格式。 要实现图像格

    2024年02月12日
    浏览(82)
  • 『CV学习笔记』Opencv和PIL Image以及base64编码互相转化

    Opencv和PIL Image以及base64编码互相转化

    2024年02月13日
    浏览(44)
  • opencv 图像色彩空间转化

    今天看了b站贾志刚的课,觉得不错,特地做学习笔记来和小伙伴分享 贾志刚的这个好像是2.0版本,30小时的,语言更加精炼,适合初级入门学习 第一节是常规安装   看他的步骤装就行了,记得配置完点应用再点确定,我第一次就是 没点然后就失败了,又得重配置一次 第二节就是基

    2024年02月22日
    浏览(46)
  • [OpenCV] CV_32F与CV_8U之间的数据类型转换

    最近在c++使用OpenCV时,总会因为类型转换为发生图片颜色错误,在网上查了些方法都不适用,总结下自己探索的经验。 经常使用的是8UC(n)与32FC(n),其中8U在0-255之间使用整数对应颜色,32F在0-1之间使用小数对应颜色; 在使用 converTo() 进行数据类型转换时,数据值并不会发生内

    2024年02月12日
    浏览(53)
  • Opencv 图像处理:图像基础操作与灰度转化

    本文已收录于Opencv系列专栏: 深入浅出OpenCV ,专栏旨在详解Python版本的Opencv,为计算机视觉的开发与研究打下坚实基础。免费订阅,持续更新。 1.图像格式 图像压缩比: 通过编码器压缩后的图象数字大小和原图象数字大小的压缩比。 BMP 格式 Windows系统下的 标准位图格式 ,

    2024年02月04日
    浏览(51)
  • OpenCV数据类型及CV_16UC1深度图ros订阅

    最近用到深度图,对其数据类型及显示有些迷惑,记笔记于此:

    2024年02月05日
    浏览(41)
  • PIL、OpenCV、numpy处理图像格式的相互转化方式

    OpenCV读取图像后返回的是一个代表图像的NumPy数组,采用的格式是 H×W×C,通道顺序为BGR 使用matplotlib绘图时,可以读取tesnor和numpy数据类型,图片通道顺序为RGB,且尺寸为(H,W,C)。 使用np.array(image)和np.asarray(image)可以将 PIL Image 图像转换成 numpy 数组。 使用Image.fromarray(np.uint8(i

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包