飞机的卧铺 2024-02-28 18:11 采纳率: 0%
浏览 85

ros2发布订阅一张图片(C++)

ROS2 :发布端发布一张图片,订阅端订阅这张图片并显示在屏幕上,利用C++ opencv 来实现。

  • 写回答

3条回答 默认 最新

  • 关注

    tyq17733829193 晚上好🌙🌙🌙
    本答案参考通义千问

    要在ROS 2中使用C++和OpenCV来实现图像的发布和订阅,你需要遵循以下步骤:

    1. 安装依赖库:

      • 首先,确保你已经安装了ROS 2、ament构建系统、以及OpenCV。你可以使用ros2命令行工具来安装这些依赖:
        ros2 system install ament_cmake_opencv
        
    2. 创建ROS节点:

      • 创建两个节点:一个用于发布图像,另一个用于订阅并显示图像。
      • 在发布节点中,创建一个发布者,使用sensor_msgs/msg/Image消息类型,这是ROS中用来表示图像的标准消息。
      • 在订阅节点中,创建一个订阅者,并在回调函数中处理接收到的图像。

    发布端(publisher.cpp):

    #include <rclcpp/rclcpp.hpp>
    #include <sensor_msgs/image_encodings.h>
    #include <opencv2/opencv.hpp>
    
    class ImagePublisher : public rclcpp::Node
    {
    public:
      ImagePublisher()
        : image_pub_(this->create_publisher<sensor_msgs::msg::Image>("image_topic", 10))
      {
        // 创建一个OpenCV图像
        cv::Mat img = ...; // 填充你的图像数据
    
        // 将OpenCV图像转换为ROS消息
        sensor_msgs::msg::Image msg;
        cv_bridge::toImageMsg(img, "bgr8", &msg);
    
        // 发布图像
        this->image_pub_->publish(msg);
      }
    
    private:
      rclcpp::Publisher<sensor_msgs::msg::Image> image_pub_;
    };
    
    int main(int argc, char * argv[])
    {
      rclcpp::init(argc, argv);
      auto node = rclcpp::Node::make_shared<ImagePublisher>("image_publisher");
      rclcpp::spin(node);
      rclcpp::shutdown();
      return 0;
    }
    

    订阅端(subscriber.cpp):

    #include <rclcpp/rclcpp.hpp>
    #include <sensor_msgs/image_encodings.h>
    #include <opencv2/opencv.hpp>
    #include <image_transport/image_transport.h>
    #include <cv_bridge/cv_bridge.h>
    
    class ImageSubscriber : public rclcpp::Node
    {
    public:
      ImageSubscriber()
        : image_sub_(this->create_subscription<sensor_msgs::msg::Image>("image_topic", 10,
          [this](const sensor_msgs::msg::Image::SharedPtr msg) -> void {
            // 解析ROS图像消息为OpenCV图像
            cv::Mat img;
            try {
              cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, "bgr8");
              img = cv_ptr->image;
            } catch (cv_bridge::Exception& e) {
              RCLCPP_ERROR(this->get_logger(), "Could not convert image: %s", e.what());
              return;
            }
    
            // 显示图像
            cv::imshow("Received Image", img);
            cv::waitKey(1);
          }))
      {}
    
    private:
      rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr image_sub_;
    };
    
    int main(int argc, char * argv[])
    {
      rclcpp::init(argc, argv);
      auto node = rclcpp::Node::make_shared<ImageSubscriber>("image_subscriber");
      rclcpp::spin(node);
      rclcpp::shutdown();
      return 0;
    }
    
    1. 构建和运行:
      • 使用ament构建系统构建你的程序:
        cd <your_project_directory>
        colcon build
        
      • 运行发布节点:
        colcon run --node-image=image_publisher_node
        
      • 运行订阅节点:
        colcon run --node-image=image_subscriber_node
        

    现在,发布节点会定期发布图像,而订阅节点会接收并显示这些图像。注意,你需要在发布端创建图像时填充实际的图像数据。

    评论

报告相同问题?

问题事件

  • 创建了问题 2月28日

悬赏问题

  • ¥15 R语言绘制生存曲线时出现警告:All aesthetics have length 1, but the data has 2 rows.
  • ¥15 pyqt怎么把滑块和输入框相互绑定,求解决!
  • ¥20 wpf datagrid单元闪烁效果失灵
  • ¥15 券商软件上市公司信息获取问题
  • ¥100 ensp启动设备蓝屏,代码clock_watchdog_timeout
  • ¥15 Android studio AVD启动不了
  • ¥15 陆空双模式无人机怎么做
  • ¥15 想咨询点问题,与算法转换,负荷预测,数字孪生有关
  • ¥15 C#中的编译平台的区别影响
  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?