ROS下cv_bridge和opencv互转

参看roswiki:

http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages


注意其中的源码编译好后,在运行时,要输入视频流

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);
  }


其中/camera/image_raw 为图像消息,程序订阅该消息获取图像./image_converter/output_video为程序产生的话题消息.

Demo code如下:

Here is a node that listens to a ROS image message topic, converts the image into a cv::Mat, draws a circle on it and displays the image using OpenCV. The image is then republished over ROS. (这里是一个监听ROS图像消息主题的节点,将图像转换为cv :: Mat,并在其上绘制一个圆圈并使用OpenCV显示图像。 该图像然后通过ROS重新发布。)

In your package.xml and CMakeLists.xml (or when you use catkin_create_pkg), add the following dependencies:

sensor_msgs
cv_bridge
roscpp
std_msgs
image_transport

Create a image_converter.cpp file in your /src folder and add the following:

The complete code
#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>

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;
    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
    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;
}

Let's break down the above node:


   2 #include <image_transport/image_transport.h>
   3 

Using image_transport for publishing and subscribing to images in ROS allows you to subscribe to compressed image streams. Remember to include image_transport in your package.xml. (使用image_transport在ROS中发布和订阅图像可以让您订阅压缩的图像流。请记住在package.xml中包含image_transport。)

Toggle line numbers
   3 #include <cv_bridge/cv_bridge.h>
   4 #include <sensor_msgs/image_encodings.h>
   5 

Includes the header for CvBridge as well as some useful constants and functions related to image encodings. Remember to include cv_bridge in your package.xml. (包括CvBridge的头文件以及一些与图像编码相关的有用的常量和函数。 记得在你的package.xml中包含cv_bridge。 )


   5 #include <opencv2/imgproc/imgproc.hpp>
   6 #include <opencv2/highgui/highgui.hpp>
   7 

Includes the headers for OpenCV's image processing and GUI modules. Remember to include opencv2 in your package.xml. (包括OpenCV图像处理和GUI模块的的头文件。 请记住在你的package.xml中包含opencv2。)


  12   ros::NodeHandle nh_;
  13   image_transport::ImageTransport it_;
  14   image_transport::Subscriber image_sub_;
  15   image_transport::Publisher image_pub_;
  16 
  17 public:
  18   ImageConverter()
  19     : it_(nh_)
  20   {
  21     // Subscrive to input video feed and publish output video feed
  22     image_sub_ = it_.subscribe("/camera/image_raw", 1,
  23       &ImageConverter::imageCb, this);
  24     image_pub_ = it_.advertise("/image_converter/output_video", 1);

Subscribe to an image topic "in" and advertise an image topic "out" using image_transport. ( 订阅图像主题“in”并使用image_transport将图像主题"out"发布出去。)


  26     cv::namedWindow(OPENCV_WINDOW);
  27   }
  28 
  29   ~ImageConverter()
  30   {
  31     cv::destroyWindow(OPENCV_WINDOW);
  32   }

OpenCV HighGUI calls to create/destroy a display window on start-up/shutdown. (OpenCV HighGUI调用在启动/关闭时创建/销毁显示窗口).


  34   void imageCb(const sensor_msgs::ImageConstPtr& msg)
  35   {
  36     cv_bridge::CvImagePtr cv_ptr;
  37     try
  38     {
  39       cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
  40     }
  41     catch (cv_bridge::Exception& e)
  42     {
  43       ROS_ERROR("cv_bridge exception: %s", e.what());
  44       return;
  45     }

In our subscriber callback, we first convert the ROS image message to a CvImage suitable for working with OpenCV. Since we're going to draw on the image, we need a mutable copy of it, so we use toCvCopy(). sensor_msgs::image_encodings::BGR8 is simply a constant for "bgr8", but less susceptible to typos.

Note that OpenCV expects color images to use BGR channel order.

You should always wrap your calls to toCvCopy() / toCvShared() to catch conversion errors as those functions will not check for the validity of your data.


  47     // Draw an example circle on the video stream
  48     if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
  49       cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));
  50 
  51     // Update GUI Window
  52 

Draw a red circle on the image, then show it in the display window.


  53     cv::waitKey(3);

Convert the CvImage to a ROS image message and publish it on the "out" topic.

To run the node, you will need an image stream. Run a camera or play a bag file to generate the image stream. Now you can run this node, remapping "in" to the actual image stream topic.

If you have successfully converted images to OpenCV format, you will see a HighGui window with the name "Image window" and your image+circle displayed.

You can see whether your node is correctly publishing images over ROS using either rostopic or by viewing the images using image_view.
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值