ros2--图像/image

ros2中传输图像的接口

sensor_msgs/msg/Image

ros2的image接口需要配合而opencv和cv_bridge一起使用。

案例(发布,订阅和保存和显示):

发布:

复制代码
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>

class ImagePublisher : public rclcpp::Node {
public:
    ImagePublisher() : Node("image_publisher") {
        RCLCPP_INFO(this->get_logger(), "Image publisher node has been started.");
        this->declare_parameter<std::string>("image_abs_path", "");
        image_abs_path_ = this->get_parameter("image_abs_path").as_string();
        publisher_ = this->create_publisher<sensor_msgs::msg::Image>("camera/image", 10);
        timer_ = this->create_wall_timer(std::chrono::seconds(3), std::bind(&ImagePublisher::publishImage, this));
    }

private:
    void publishImage() {
        RCLCPP_INFO(this->get_logger(), "image_abs_path: %s", image_abs_path_.c_str());
        cv::Mat image = cv::imread(image_abs_path_, cv::IMREAD_COLOR); // 读取图像文件
        if (!image.empty()) {
            sensor_msgs::msg::Image msg;
            cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", image).toImageMsg(msg); // 转换为ROS Image消息类型
            publisher_->publish(msg); // 发布图像消息
            RCLCPP_INFO(this->get_logger(), "Image has been published.");
        } else {
            RCLCPP_ERROR(this->get_logger(), "Image loading failed!");
        }
    }

private:
    std::string image_abs_path_{""};
    rclcpp::Publisher<sensor_msgs::msg::Image>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char** argv) {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ImagePublisher>());
    rclcpp::shutdown();
    return 0;
}

订阅:

复制代码
#include <rclcpp/rclcpp.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <opencv2/opencv.hpp>
#include <cv_bridge/cv_bridge.h>
#include <functional>

class ImageSubscriber : public rclcpp::Node {
public:
    ImageSubscriber() : Node("image_subscriber") {
        declare_parameter("image_save_path", "");
        declare_parameter("image_name", "");
        image_save_path_ = get_parameter("image_save_path").as_string();
        image_name_ = get_parameter("image_name").as_string();
        subscription_ = this->create_subscription<sensor_msgs::msg::Image>(
            "camera/image",10, std::bind(&ImageSubscriber::image_callback, this, std::placeholders::_1));
    }

    private:
    void image_callback(const sensor_msgs::msg::Image::SharedPtr msg) {
        cv_bridge::CvImagePtr cv_ptr;
        try {
            cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
        } catch (cv_bridge::Exception& e) {
            RCLCPP_ERROR(this->get_logger(), "Failed to convert image: %s", e.what());
            return;
        }
        cv::imshow("Image window", cv_ptr->image);
        cv::waitKey(2);
        if (image_save_path_!= "" && image_name_!= "") {
            cv::imwrite(image_save_path_ + image_name_ + ".jpg", cv_ptr->image);
            RCLCPP_INFO(this->get_logger(), "Image saved to %s", (image_save_path_ + image_name_ + ".jpg").c_str());
        }
    }

private:
    std::string image_save_path_{""};
    std::string image_name_{""};
    rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr subscription_;
};

int main(int argc, char *argv[]) {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ImageSubscriber>());
    rclcpp::shutdown();
    return 0;
}
相关推荐
老四啊laosi1 天前
[C++进阶] 24. 哈希表封装unordered_map && unordered_set
c++·哈希表·封装·unordered_map·unordered_set
妙为1 天前
银河麒麟V4下编译Qt5.12.12源码
c++·qt·国产化·osg3.6.5·osgearth3.2·银河麒麟v4
史迪仔01121 天前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
会编程的土豆1 天前
【数据结构与算法】再次全面了解LCS底层
开发语言·数据结构·c++·算法
低频电磁之道1 天前
解决 Windows C++ DLL 导出类不可见的编译错误
c++·windows
君义_noip1 天前
信息学奥赛一本通 4150:【GESP2509七级】⾦币收集 | 洛谷 P14078 [GESP202509 七级] 金币收集
c++·算法·gesp·信息学奥赛·csp-s
Ricky_Theseus1 天前
静态链接与动态链接
c++
澈2071 天前
双指针,数组去重
c++·算法
小辉同志1 天前
207. 课程表
c++·算法·力扣·图论
feng_you_ying_li1 天前
C++11,{}的初始化情况与左右值及其引用
开发语言·数据结构·c++