ros-perception / image_transport_tutorials

ROS 2 tutorials for image_transport.
Apache License 2.0
50 stars 11 forks source link

How to use multiple plugins in a single process? #16

Closed Huntersdeng closed 5 months ago

Huntersdeng commented 6 months ago

When using rgb-d camera, it is quite common to subscribe its color frame and depth frame at the same time. To use plugins, I learn that the parameter "image transport" need to be set. However, to compress the color frame, "image transport" should be set to "compressed". ros2 run sub_demo image_transport_sub --ros-args -p image_transport:=compressed To compress the color frame, "image transport" should be set to "compressedDepth". ros2 run sub_demo image_transport_sub --ros-args -p image_transport:=compressedDepth How can I use multiple plugins in a single ros2 node? Any parameters to configure? Here is a sample code:

#include "cv_bridge/cv_bridge.h"
#include "image_transport/image_transport.hpp"
#include "opencv2/highgui.hpp"
#include "rclcpp/logging.hpp"
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/image.hpp"

void colorCallback(const sensor_msgs::msg::Image::ConstSharedPtr & msg) {
    cv::imshow("view1", cv_bridge::toCvShare(msg, "bgr8")->image);
    cv::waitKey(10);
}

void depthCallback(const sensor_msgs::msg::Image::ConstSharedPtr & msg)
{
    cv::Mat img = cv_bridge::toCvShare(msg, "16UC1")->image;
    double minVal, maxVal;
    cv::Point minLoc, maxLoc;
    cv::minMaxLoc(img, &minVal, &maxVal, &minLoc, &maxLoc);

    img = 255 * (img-minVal)/(maxVal-minVal+1e-8);

    cv::Mat depth_img;
    img.convertTo(depth_img, CV_8UC1);

    cv::Mat pseudoColorMap;
    cv::applyColorMap(depth_img, pseudoColorMap, cv::COLORMAP_JET);
    cv::imshow("view2", pseudoColorMap);
    cv::waitKey(10);
}

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::NodeOptions options;
  rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared("image_listener", options);
  node->declare_parameter<std::string>("image_transport", "raw");
  cv::namedWindow("view1");
  cv::namedWindow("view2");
  cv::startWindowThread();
  image_transport::ImageTransport it(node);
  image_transport::TransportHints hints(node.get());
  image_transport::Subscriber sub_color = it.subscribe("/camera/color/image_raw", 1, colorCallback, &hints);
  image_transport::Subscriber sub_depth = it.subscribe("/camera/depth/image_raw", 1, depthCallback, &hints);
  rclcpp::spin(node);
  cv::destroyWindow("view1");
  cv::destroyWindow("view2");

  return 0;
}
mikeferguson commented 6 months ago

You can change the name of the parameter used - by replacing the parameter "image_transport" with something like "depth_image_transport" - you need to declare the new parameter, and then add some constructor params to TransportHints - this is what the nodes in depth_image_proc package do - example here: https://github.com/ros-perception/image_pipeline/blob/rolling/depth_image_proc/src/point_cloud_xyz.cpp#L79

Huntersdeng commented 5 months ago

It works fine and helps a lot. Thank you for your reply.