Use of cv_bridge of ROS, image processing in ROS

Mainly introduces cv_bridgethe use in ROS.
In ROS, when a node subscribes to an image topic, it contains the image information we need to process. However, in ROS, we all process image information in opencv. How to send the image information subscribed by the node to opencv at this time? Of course, this has to be mentioned cv_bridge~~
The following is to use pictures to understand: insert image description here
Then the description of the code is basically recorded in the 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
{
    
    
  // 下面四行 属于 private 属性,只能使用类内函数进行访问(封装)
  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);
    // “/probot_anno/camera/image_raw":订阅的话题
    // 1:队列长度,即在消息队列中缓存几条消息
    // &ImageConverter::imageCb, this:其中&ImageConverter::imageCb是回调函数,用于处理订阅到的图像信息;this指针是用于确保当前对象调用回调函数时候不会出错
    image_sub_ = it_.subscribe("/probot_anno/camera/image_raw", 1,&ImageConverter::imageCb, this);
    image_pub_ = it_.advertise("/image_converter/output_video", 1);

    cv::namedWindow(OPENCV_WINDOW);
  }

  ~ImageConverter()  // 析构函数,对堆区 ImageConverter类 创建数据进行释放
  {
    
    
    cv::destroyWindow(OPENCV_WINDOW);
  }

  void imageCb(const sensor_msgs::ImageConstPtr& msg) // 对订阅到图像消息进行处理,并且返回给 it_.subscribe 对象
  {
    
    
    cv_bridge::CvImagePtr cv_ptr;  // 创建 cv_ptr 对象,它属于 cv_bridge::CvImagePtr 类型
    try
    {
    
    
      // msg:图像订阅到图像消息;
      // sensor_msgs::image_encodings::BGR8:蓝色-绿色-红色顺序的彩色图像
      cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8); // 使用cv_ptr 接收到图像消息
    }
    catch (cv_bridge::Exception& e)
    {
    
    
      ROS_ERROR("cv_bridge exception: %s", e.what());
      return;
    }

    // Draw an example circle on the video stream,其实只有下面两行才是真正使用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");  // 初始化ROS节点,节点名称:image_converter
  ImageConverter ic;
  ros::spin();   // 回旋函数,只要涉及到回调函数时候都需要使用
  return 0;
}

reference

Guess you like

Origin blog.csdn.net/weixin_56847236/article/details/131562804