ROS subscribes to the Image topic and converts it to an OpenCV image

Requirement: Get the rgb image and depth image from the topic released by the realsense camera, and perform subsequent processing. The cv_bridge class is provided in ROS to help us convert between ROS and OpenCV image formats.

The subscriber needs to define an object it with image_transport, and then define two Subscriber objects, which are used to call back the rgb and depth topics respectively.

	// 初始化ros节点
    ros::init(argc, argv, "RGBD");
    // 创建ros节点句柄
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    // 回调函数队列长度为x,因此spinOnce每次执行完队列函数,相当于每x帧取1帧
    image_transport::Subscriber rgb_sub = it.subscribe("rgb", 1, rgbCallback);
    image_transport::Subscriber depth_sub = it.subscribe("depth", 1, depthCallback);

When cv_bridge converts the ROS image message to the OpenCV image format, it is implemented through the CvImage class. Generally speaking, cv_bridge provides two ways to convert to the CvImage class, namely copy and share.

  • The toCvCopy function will copy an image data from the ROS message, no matter how the content of the CvImage class is modified, the source data will not be affected
  • The toCvShare function points the returned OpenCV pointer to the message of ROS when the source and encoding both match, that is, the shared pointer. Its characteristic is that as long as you still keep a copy of the returned CvImage class, the ROS message type will not be released.

The commonly used encodings in CvBridge are as follows:

  • mono8: CV_8UC1, grayscale image

  • mono16: CV_16UC1, 16-bit grayscale image

  • bgr8: CV_8UC3, color image with blue-green-red color order

  • rgb8: CV_8UC3, color image with red-green-blue color order

  • bgra8: CV_8UC4, BGR color image with an alpha channel

  • rgba8: CV_8UC4, RGB color image with an alpha channel

cv_bridge::toCvShare(msg, "bgr8")It is to convert msg to CV_8UC3 image, and then get the shared pointer to msg, ->imagewhich is to get the image, the format is cv::Mat. It can be understood as a shallow copy.

rgb = cv_bridge::toCvShare(msg, "bgr8")->image;

cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)Also converts msg to CV_8UC3 image, but it only points to the converted image in cv::Mat format. It can be understood as a deep copy.

cv::Mat rgb;
cv::Mat depth;

// rgb图像的回调函数,当有图像消息到达rgb时,就会被调用
void rgbCallback(const sensor_msgs::ImageConstPtr& msg) {
    
    
    try {
    
               
        // ROS图像消息——>OpenCV图像
        rgb = cv_bridge::toCvShare(msg, "bgr8")->image;
        // cv::imshow("image", rgb);
        // cv::waitKey(50);
        // cout << "I have received rgb image!" << endl;
        // rgb = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)->image;
        
    } catch(cv_bridge::Exception& e) {
    
    
        ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }
}

// depth深度图像的回调函数
void depthCallback(const sensor_msgs::ImageConstPtr& msg) {
    
    
    try {
    
               
        // ROS图像消息——>OpenCV图像
        depth = cv_bridge::toCvShare(msg, "mono16")->image;
        // cout << "I have received depth image!" << endl;
    } catch(cv_bridge::Exception& e) {
    
    
        ROS_ERROR("Could not convert from '%s' to 'mono16'.", msg->encoding.c_str());
    }
}

People say it is a peony, but Buddha says it is a flower arrow. Shoot people into the bone marrow, die without complaint.

Guess you like

Origin blog.csdn.net/qq_42257666/article/details/131492112