ROS图像处理相关

17 篇文章 3 订阅

cv_bridge

ROS以自己的sensor_msgs/Image消息格式传递图像,但用户希望将图像与OpenCV结合使用。在OpenCV中,图像以Mat矩阵的形式存储。
cv_bridge是一个ROS库,提供ROS图像和OpenCV图像之间的转换接口。
在这里插入图片描述
cv_bridge包定义了一个CvBridge类,用来接收ROS Image消息

namespace cv_bridge {
class CvImage
{
      public:
      std_msgs::Header header;
      std::string encoding;
      cv::Mat image;
};
typedef boost::shared_ptr<CvImage> CvImagePtr;
typedef boost::shared_ptr<CvImage const> CvImageConstPtr;
}

ROS->OpenCV

在使用时有两种情形:

  1. 想修改数据,必须复制一份ROS消息数据拷贝。
  2. 不修改数据,可以安全地共享ROS消息所拥有的数据,而不复制。
// Case 1: Always copy, 返回一个可修改的CvImage指针
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr& source,
                    const std::string& encoding = std::string());
CvImagePtr toCvCopy(const sensor_msgs::Image& source,
                    const std::string& encoding = std::string());// Case 2: Share if possible, 返回const CvImage指针
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr& source,
                          const std::string& encoding = std::string());
CvImageConstPtr toCvShare(const sensor_msgs::Image& source,
                          const boost::shared_ptr<void const>& tracked_object,
                          const std::string& encoding = std::string());

输入参数是图像消息(指针)和可选的目标图像编码参数。

  • 如果源图像消息编码格式与参数编码格式匹配,则toCvShare会将返回指向ROS消息数据的cv::Mat,从而避免复制。只要您持有已返回的CvImage对象,ROS消息数据就不会被释放。
  • 如果编码格式不匹配,它将分配一个新的缓冲区并执行转换。不允许修改返回的CvImage,因为它可能与ROS image消息共享数据,而ROS image消息又可能与其他回调共享。

如果没有给定编码信息(或者更确切地说,空字符串),目标图像编码将与图像消息编码相同,在这种情况下,toCvShare能保证不会复制图像数据。
编码格式定义在sensor_msgs::image_encodings::

  • 8UC[1-4]
  • 8SC[1-4]
  • 16UC[1-4]
  • 16SC[1-4]
  • 32SC[1-4]
  • 32FC[1-4]
  • 64FC[1-4]
  • rgb8
  • rgba8
  • rgb16
  • rgba16
  • bgr8
  • bgra8
  • bgr16
  • bgra16
  • mono8
  • mono16

OpenCV->ROS

要将CvImage转换为ROS图像消息,请使用toImageMsg成员函数:

class CvImage
 {
   sensor_msgs::ImagePtr toImageMsg() const;
   // Overload mainly intended for aggregate messages that contain
   // a sensor_msgs::Image as a member.
   void toImageMsg(sensor_msgs::Image& ros_image) const;
 };

image_transport

image_transport包用于传输图片,程序以插件的形式给出,传输格式包括JPEG/PNG压缩图片格式和Thero视频流。

// Use the image_transport classes instead.
#include <ros/ros.h>
#include <image_transport/image_transport.h>

void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
  // ...
}

ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Subscriber sub = it.subscribe("in_image_base_topic", 1, imageCallback);
image_transport::Publisher pub = it.advertise("out_image_base_topic", 1);

image_transport Publishers

image_transport publishers的使用和ROS一样,会提供一系列传输选项(JPEG compression,streaming video.etc)。不同的subscribers可以使用不同的transports策略从相同的publisher请求图片。
C++: image_transport::Publisher (API), image_transport::CameraPublisher (API)

Published topics

image_transport publishers为每一个transport发布单独的ROS Topic。
原始图片sensor_msgs/Image发布base_topic。如果有额外的插件使用,他们发布消息到base topic的子话题,格式为<base topic>/<transport name>

Parameters

image_transport publishers没有独立的参数,但是可以通过Parameter Server实现reconfigure。
可以通过dynamic_reconfigure包来调整参数
参数格式为:
<base topic>/<transport name><parameter name>
例如:
/camera/image/compressed/jpeg_quality

image_transport Subscribers

C++: image_transport::Subscriber (API), image_transport::CameraSubscriber (API)

node

$ rosrun image_transport republish [in_transport] in:=<in_base_topic> [out_transport] out:=<out_base_topic>

in_transportout_transport是图片传输格式:raw compressedthero,对应原始图片格式、压缩图片格式和视频流格式。
假设我们使用theora视频流传输格式来发布机器人的图像。我们有几个节点收听图像主题。为了不让每个节点都单独将视频流转换为原始图片格式,浪费资源,使用image_transport包的republish节点将视频流式转换为sensor_msgs/image messages格式,重新发布到topic:

$ rosrun image_transport republish theora in:=camera/image raw out:=camera/image_decompressed

opencv编解码函数

#include <fstream>
#include <vector>
#include <opencv2/opencv.hpp>
std::string image_name = "path/to/.jpg";
std::ifstream file(image_name.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::string buffer(size, ' ');
file.read(&buffer[0], size);
file.close();
//解码
std::vector<char> vec_data(&buffer[0], &buffer[0] + size);
cv::Mat mat = cv::imdecode(vec_data, CV_LOAD_IMAGE_COLOR);
//编码
std::vector<uchar> buf;
cv::imencode(".jpg", mat, buf);

参考资料

image_transport-ROS-wiki
https://blog.csdn.net/fengbingchun/article/details/60780232

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shilong Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值