背景:某些情况下需要录图像数据的包,非常占空间和带宽,尤其对于一些工业相机图像一张好几兆,每秒30帧的话一份钟好几个G,这时候可以选择的订阅压缩图像,下面直接来个demo。
先订阅一个sensor::Image 消息,然后使用image_transport直接发布图像,会同时产生一个压缩image_compressed/compressed和不压缩的image_compressed图像话题,订阅时直接订阅压缩话题即可。
#include "ros/ros.h"
#include "sensor_msgs/Image.h"
#include "sensor_msgs/CompressedImage.h"
#include "sensor_msgs/image_encodings.h"
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
cv::Mat imgCallback;
image_transport::Publisher image_pub;
static void ImageCallback(const sensor_msgs::ImageConstPtr &msg)
cout<<"FLIR time:"<<msg->header.stamp<<endl;
return;
image_pub.publish(msg);
cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);
imgCallback = cv_ptr->image;
cv::imshow("imgCallback",imgCallback);
cv::waitKey(1);
cout<<"cv_ptr: "<<cv_ptr->image.cols<<" h: "<<cv_ptr->image.rows<<endl;
//std::cout<<"Image: "<<msg->width<<" x "<<msg->height<<std::endl;
catch (cv_bridge::Exception& e)
//ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
//ROS_ERROR("Could not convert from '%s' to 'bgr8'.",msg->format.c_str());
//原文链接:https://blog.csdn.net/qq_30460905/article/details/80489841
int main(int argc, char **argv)
ros::init(argc, argv, "CompressedImage");
ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Subscriber image_sub;
std::string image_topic = "usb_cam/image_raw";
image_sub = it.subscribe(image_topic,10,ImageCallback);
image_pub = it.advertise("image_compressed",1);
ros::spin();
return 0;
订阅压缩图像话题消息很简单,直接用ros::Publisher订阅即可
#include "ros/ros.h"
#include "sensor_msgs/CompressedImage.h"
#include "sensor_msgs/image_encodings.h"
#include <cv_bridge/cv_bridge.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
cv::Mat imgCallback;
static void ImageCallback(const sensor_msgs::CompressedImageConstPtr &msg)
cv_bridge::CvImagePtr cv_ptr_compressed = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);
imgCallback = cv_ptr_compressed->image;
cv::imshow("imgCallback",imgCallback);
cv::waitKey(1);
cout<<"cv_ptr_compressed: "<<cv_ptr_compressed->image.cols<<" h: "<<cv_ptr_compressed->image.rows<<endl;
catch (cv_bridge::Exception& e)
//ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
int main(int argc, char **argv)
ros::init(argc, argv, "CompressedImage");
ros::NodeHandle nh;
ros::Subscriber image_sub;
std::string image_topic = "image_compressed/compressed";
image_sub = nh.subscribe(image_topic,10,ImageCallback);
ros::Rate loop_rate(10);
while (ros::ok())
ROS_INFO("ROS OK!");
ros::spinOnce();
loop_rate.sleep();
return 0;
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(compress_Image)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
find_package(catkin REQUIRED COMPONENTS
roscpp sensor_msgs cv_bridge image_transport
find_package(OpenCV 3.3 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIBRARY_DIRS})
catkin_package()
include_directories(
# include
${catkin_INCLUDE_DIRS}
add_executable(${PROJECT_NAME}_sub src/compress_sub.cpp)
## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_sub
${catkin_LIBRARIES}
${OpenCV_LIBRARIES}
背景:某些情况下需要录图像数据的包,非常占空间和带宽,尤其对于一些工业相机图像一张好几兆,每秒30帧的话一份钟好几个G,这时候可以选择的订阅压缩图像,下面直接来个demo。先订阅一个sensor::Image 消息,然后使用image_transport直接发布图像,会同时产生一个压缩image_compressed/compressed和不压缩的image_compressed图像话题,订阅时直接订阅压缩话题即可。#include "ros/ros.h"#include "sensor_msg
该例程主要用于
ROS之间
压缩图像的传输,
ROS发布压缩图像的速度比传输原
图像的速度快很多,而工业相机一般都会
发布压缩图像。本程序包将
压缩图像功能封装成一个类,在launch
中即可设置
压缩图像话题、
发布话题、输出图片路径等。另外也上传了几个样本可参考,launch文件具体如下:
<!---->
经常存在这种情况, 我们需要在移动设备上录制一些包含图像信息的rosbag, 但是如果录制raw格式的话,占的内存空间太大, 一般可以采用录制compressed模式; 但是一般的代码中,图像从sensor_msgs转换到cv::Mat都是通过原图像,即raw类型的topic, 这时可以我们自己手动添加函数, 即可以订阅compressed topic的类型; 或者如果该代码实在麻烦,也可以之间将录制好的comppressed包转换成raw格式;
haha@haha:/opt/ros/kinetic/l
如果用ros的 image_transport::Publisher 发布图片的话则,ros会自动添加一个 image/compressed的topic,将原始图像编码,编码方式可以设置为png\jpeg.
有时候我们获取到的图片就是编码之后的数据,这个时候如果将解码转成 cv::Mat 再pub的话 性能开销比较大,并且数据损失更大. 所以我们可以直接pub compressed.
注意 我们使...
最近工作过程
中有一个小问题,一个
ROS节点要处理另一个
ROS节点的图片信息,因为相机传的图片分辨率为1920*1080,造成图片较大,在
ROS传输过程
中造成了比较大的延时,所以想通过图片
压缩将发送的图片信息变小,减少时延,经过图片
压缩后最后的效果也十分明显。
具体原理是把
ros中代表图片的信息sensor_msgs::
Image通过cvbridge转化成opencv
中的Mat数据格式,在使用Resize函数将其
压缩,最后再通过cvbridge转化成sensor_msgs::
Image。
具体实现函数:
在 ROS 中,可以通过 `ros::NodeHandle` 类来发布消息。首先,你需要创建一个 `ros::NodeHandle` 对象,然后调用它的 `advertise` 方法来创建一个发布者。
#include <ros/ros.h>
#include <std_msgs/Int32.h>
int main(int argc, char **argv)
// 初始化 ROS 节点
ros::init(argc, argv, "my_node");
// 创建节点句柄
ros::NodeHandle nh;
// 创建一个发布者,发布消息到名为 "my_topic" 的话题
ros::Publisher pub = nh.advertise<std_msgs::Int32>("my_topic", 1000);
// 你的代码
return 0;
接下来,你可以通过调用发布者的 `publish` 方法来发布消息。
std_msgs::Int32 msg;
msg.data = 10;
pub.publish(msg);
注意,在发布消息之前,你需要先将消息的内容填充到消息对象中。