当前位置:   article > 正文

ROS 发布和订阅压缩图像消息 sensor_msgs/Image 和 sensor_msgs/CompressedImage_ros发布和订阅压缩消息

ros发布和订阅压缩消息

1. image_transport

     image_transport是一个用于实现图像传输的工具包,它提供了一种灵活的方式来订阅和发布图像数据,但它并不直接操作消息类型。

    使用 image_transport 将发送的图像转发为压缩图像
    如果不想写程序对图像进行处理,可以使用 image_transport 包的命令行工具来将 Image 消息转发为 CompressedImage 消息

rosrun image_transport republish raw in:=/image compressed out:=/image

   该节点会自动订阅/image话题下的Image消息,并将CompressedImage格式的消息发送到/image/compressed话题下
 

2.sensor_msgs/Image 和 sensor_msgs/CompressedImage

    (1)两者的关系  

sensor_msgs/Image 和 sensor_msgs/CompressedImage 是 ROS 中用于传输图像数据的两种不同消息类型,它们有一些显著的区别:

    数据格式
        sensor_msgs/Image:原始的未经压缩的图像消息,通常用于传输原始图像数据,例如 RGB、灰度或深度图像。
        sensor_msgs/CompressedImage:经过压缩的图像消息,以减少数据量。压缩格式通常是 JPEG 或 PNG。

    数据量:
        sensor_msgs/Image 包含原始图像数据,因此它可能会占用较多的带宽和存储空间。
        sensor_msgs/CompressedImage 则通过压缩算法减少了数据量,因此在传输和存储时需要的带宽和空间更少。

    传输效率
        由于 sensor_msgs/CompressedImage 的数据量较小,因此在网络传输中具有更高的效率,尤其是在带宽受限的情况下。
        sensor_msgs/Image 虽然保留了图像的所有信息,但在传输过程中可能需要更多的带宽和资源。

(2)sensor_msgs/Image

  sensor_msgs/Image 是ROS(机器人操作系统)中定义的一种消息类型,用于在ROS系统中传输图像数据。该消息类型通常用于机器人视觉、图像处理和计算机视觉应用中。

sensor_msgs/Image 消息格式通常包含以下字段:

  • header: 用于存储消息的元数据,如时间戳、坐标系等信息。
  • height: 图像的高度(以像素为单位)。
  • width: 图像的宽度(以像素为单位)。
  • encoding: 图像数据的编码格式,常见的编码格式包括 "rgb8"、"bgr8"、"mono8" 等。
  • is_bigendian: 表示图像数据是否采用大端字节顺序。
  • step: 表示每一行图像数据所占用的字节数。
  • data: 存储图像数据的字节数组。 

以下是一个 sensor_msgs/Image 消息的示例:

  1. header:
  2. seq: 0
  3. stamp:
  4. secs: 1622525477
  5. nsecs: 123456789
  6. frame_id: "camera_frame"
  7. height: 480
  8. width: 640
  9. encoding: "rgb8"
  10. is_bigendian: 0
  11. step: 1920
  12. data: [255, 0, 0, 255, 255, ...]

(3)sensor_msgs/CompressedImage

   sensor_msgs/CompressedImage是ROS(机器人操作系统)中用于传输压缩图像数据的消息类型之一。它允许在ROS系统中传输图像数据,同时减少带宽占用和传输延迟。

该消息类型包含以下字段:

    header:用于存储消息头信息,如时间戳和帧ID。
    format:字符串,表示图像编码格式,例如“jpeg”、“png”等。
    data:字节数组,存储压缩后的图像数据。

以下是一个 sensor_msgs/CompressedImage 消息的示例:

  1. header:
  2. seq: 0
  3. stamp:
  4. secs: 1622525477
  5. nsecs: 123456789
  6. frame_id: "camera_frame"
  7. format: "jpeg"
  8. data: [255, 216, 255, 224, 0, ...]

3. 发布压缩图像

  1. #include <ros/ros.h>
  2. #include <image_transport/image_transport.h>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <cv_bridge/cv_bridge.h>
  5. #include <sensor_msgs/CompressedImage.h>
  6. int main(int argc, char** argv)
  7. {ros::init(argc, argv, "image_publisher");
  8. ros::NodeHandle nh;
  9. ros::Publisher pub = nh.advertise<sensor_msgs::CompressedImage>("compressed_image", 1);
  10. ros::Publisher pubO = nh.advertise<sensor_msgs::Image>("image_raw", 1);
  11. cv::Mat image = cv::imread("./0000.jpg", CV_LOAD_IMAGE_COLOR);
  12. sensor_msgs::CompressedImage compressed_msg;
  13. std::vector<int> compression_params;
  14. compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
  15. compression_params.push_back(95);
  16. compressed_msg.header.stamp = ros::Time::now();
  17. compressed_msg.format = "jpeg";
  18. cv::imencode(".jpg", image, compressed_msg.data, compression_params);
  19. sensor_msgs::ImagePtr raw_msg=cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
  20. ros::Rate loop_rate(5);
  21. while (nh.ok()) {
  22. pub.publish(compressed_msg);
  23. pubO.publish(raw_msg);//发布图像消息
  24. ros::spinOnce();
  25. loop_rate.sleep();
  26. }
  27. return 0;
  28. }

4. 接收压缩图像

  1. #include <ros/ros.h>
  2. #include <sensor_msgs/CompressedImage.h>
  3. #include <opencv2/opencv.hpp>
  4. #include <cv_bridge/cv_bridge.h>
  5. // 回调函数,处理接收到的压缩图像数据
  6. void imageCallback(const sensor_msgs::CompressedImage::ConstPtr& msg)
  7. {
  8. cv_bridge::CvImagePtr cv_ptr;
  9. try
  10. {
  11. // Convert compressed image message to OpenCV image
  12. cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
  13. }
  14. catch (cv_bridge::Exception& e)
  15. {
  16. ROS_ERROR("cv_bridge exception: %s", e.what());
  17. return;
  18. }
  19. // Access the image using cv::Mat
  20. cv::Mat image = cv_ptr->image;
  21. // 在这里可以对图像进行进一步处理,例如显示、保存等操作
  22. cv::imshow("Received Image", image);
  23. cv::waitKey(1);
  24. }
  25. int main(int argc, char** argv)
  26. {
  27. // 初始化ROS节点
  28. ros::init(argc, argv, "image_subscriber");
  29. // 创建节点句柄
  30. ros::NodeHandle nh;
  31. // 创建一个订阅者,订阅名为"/compressed_image"的话题,回调函数为imageCallback
  32. ros::Subscriber sub = nh.subscribe("/compressed_image", 1, imageCallback);
  33. // 初始化OpenCV窗口
  34. // cv::namedWindow("Received Image", cv::WINDOW_AUTOSIZE);
  35. // 循环等待回调函数
  36. ros::spin();
  37. return 0;
  38. }

5. CMakeLists.txt

  1. cmake_minimum_required(VERSION 2.8.3)
  2. project(msg2image)
  3. ## Compile as C++11, supported in ROS Kinetic and newer
  4. add_compile_options(-std=c++11)
  5. ## Find catkin macros and libraries
  6. ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
  7. ## is used, also find other catkin packages
  8. find_package(catkin REQUIRED COMPONENTS
  9. cv_bridge
  10. image_transport
  11. roscpp
  12. rospy
  13. sensor_msgs
  14. std_msgs
  15. )
  16. find_package(PCL REQUIRED)
  17. find_package(OpenCV REQUIRED)
  18. catkin_package(
  19. # INCLUDE_DIRS include
  20. # LIBRARIES msg2image
  21. # CATKIN_DEPENDS cv_bridge image_transport roscpp rospy sensor_msgs std_mags
  22. # DEPENDS system_lib
  23. )
  24. include_directories(
  25. include ${catkin_INCLUDE_DIRS}
  26. ${PROJECT_NAME}
  27. ${OpenCV_INCLUDE_DIRS}
  28. )
  29. add_executable(ImageCompressedpub src/ImageCompressedpub.cpp)
  30. add_dependencies(ImageCompressedpub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
  31. target_link_libraries(ImageCompressedpub ${catkin_LIBRARIES} ${OpenCV_LIBS})
  32. add_executable(Imdecodesub src/Imdecodesub.cpp)
  33. add_dependencies(Imdecodesub ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
  34. target_link_libraries(Imdecodesub ${catkin_LIBRARIES} ${OpenCV_LIBS})

6.发布原始图像

  1. #include <ros/ros.h>
  2. #include <image_transport/image_transport.h>
  3. #include <sensor_msgs/image_encodings.h>
  4. #include <opencv2/opencv.hpp>
  5. #include <cv_bridge/cv_bridge.h>
  6. int main(int argc, char** argv) {
  7. ros::init(argc, argv, "image_publisher");
  8. ros::NodeHandle nh;
  9. image_transport::ImageTransport it(nh);
  10. image_transport::Publisher pub = it.advertise("compressed_image_topic", 1);
  11. // 打开图像文件或者从摄像头捕获图像
  12. cv::Mat image = cv::imread("./0000.jpg", cv::IMREAD_COLOR);
  13. ros::Rate loop_rate(10); // 发布频率,这里设定为10Hz
  14. while (nh.ok()) {
  15. sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
  16. pub.publish(msg);
  17. ros::spinOnce();
  18. loop_rate.sleep();
  19. }
  20. return 0;
  21. }

7.接收原始图像

  1. #include <ros/ros.h>
  2. #include <image_transport/image_transport.h>
  3. #include <cv_bridge/cv_bridge.h>
  4. #include <sensor_msgs/image_encodings.h>
  5. #include <opencv2/imgproc/imgproc.hpp>
  6. #include <opencv2/highgui/highgui.hpp>
  7. #include<iostream>
  8. #include <sensor_msgs/Image.h>
  9. #include <ros/time.h>
  10. using namespace std;
  11. using namespace cv;
  12. long int count_ =0000;//不能命名成count
  13. int n=0;
  14. void imageCallback(const sensor_msgs::ImageConstPtr& msg)
  15. {
  16. cv_bridge::CvImagePtr cv_ptr;
  17. try //对错误异常进行捕获,检查数据的有效性
  18. {
  19. cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
  20. char base_name[256];
  21. if(n%7==0)
  22. {
  23. sprintf(base_name,"./120H/%04ld.jpg",count_++);
  24. //std::sprintf(base_name,"./image/%ld.jpg", msg->header.stamp.toNSec());//获取ROS时间戳
  25. cv::imwrite(base_name, cv_ptr->image);
  26. ROS_INFO_STREAM("Saved image to " << base_name);
  27. }
  28. n++;
  29. std::cout<<"n= "<<n<<std::endl;
  30. }
  31. catch(cv_bridge::Exception& e) //异常处理
  32. {
  33. ROS_ERROR("cv_bridge exception: %s", e.what());
  34. return;
  35. }
  36. // // 获取ROS时间戳并生成文件名
  37. // std::string filename =std::to_string(msg->header.stamp.toNSec()) + ".jpg";
  38. // // 保存图像到文件
  39. // cv::imwrite(filename, cv_ptr->image);
  40. // ROS_INFO_STREAM("Saved image to " << filename);
  41. }
  42. int main(int argc, char** argv)
  43. {
  44. ros::init(argc, argv, "msg2img2");
  45. ros::NodeHandle nh_;
  46. ros::Subscriber image_sub_ = nh_.subscribe("/tztek/camera0",1, imageCallback);///middle/pylon_camera_node/image_raw/compressed
  47. ros::spin();
  48. return 0;
  49. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/845627
推荐阅读
相关标签
  

闽ICP备14008679号