本文共 2724 字,大约阅读时间需要 9 分钟。
ROS是机器人领域中比较受到关注的一种系统,它的应用比较方便而且有许多的工具比如传感器驱动包可以直接使用。但是ROS对于传感器数据有自己的格式和规范。而在OpenCV中,图像是以Mat矩阵的形式存储的,这与ROS定义的图像消息的格式有一定的区别,所以我们需要利用cv_bridge将这两种不相同的格式联系起来,如下图所示
1. ROS图像消息转换为OpenCV图像的函数
cv_bridge源码中执行转换的类为CvImage,该类包含了OpenCV的Mat格式的图像、该消息的encoding以及ROS header。类在源码中的定义如下:namespace cv_bridge { class CvImage { public: std_msgs::Header header; std::string encoding; cv::Mat image; }; typedef boost::shared_ptrCvImagePtr; typedef boost::shared_ptr CvImageConstPtr;}
当cv_bridge将ROS的图像消息转换为OpenCV图像格式时都是通过CvImage类实现的。一般来说,cv_bridge提供了两种方式转换为CvImage类,分别为复制(copy)和共享(share)。
// Case 1: Always copy, returning a mutable 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, returning a 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& tracked_object, const std::string& encoding = std::string());
上面是这两类方式实现的函数对应为toCvCopy和toCvShare,两个函数的输入有两个:图像消息的指针和可选的编码参数。这两个函数的区别:
(1)toCvCopy函数会从ROS消息中拷贝一个图像数据,不管如何修改CvImage类的内容都不会影响源数据,使用例子如下。
cv::Mat img;cv_bridge::CvImagePtr cv_ptr;cv_ptr = cv_bridge::toCvCopy(msg, "mono8");cv_ptr->image.copyTo(img);
(2)toCvShare函数则是在源和编码都匹配的情况下将返回的OpenCV指针指向ROS的消息,即共享指针地址。它的特点是只要你还保持着返回的CvImage类的副本,那么ROS的消息类型就不会被释放。当编码参数不匹配时,它还能够另外开辟一个新的缓存区并执行编码参数转换工作。toCvShare函数对于有一个指向另一个相同类型消息的指针时会很方便(比如双目图像)。如果没有给定编码类型时,toCvShare会使目标图像编码将会与消息编码相同。toCvShare函数的使用例子如下。
cv::Mat img;cv_bridge::CvImageConstPtr cv_ptr;cv_ptr=cv_bridge::toCvShare(msg, "mono8");img = cv_ptr->image;
CvBridge中常用的编码有以下那么几种:
mono8: CV_8UC1, grayscale imagemono16: CV_16UC1, 16-bit grayscale imagebgr8: CV_8UC3, color image with blue-green-red color orderrgb8: CV_8UC3, color image with red-green-blue color orderbgra8: CV_8UC4, BGR color image with an alpha channelrgba8: CV_8UC4, RGB color image with an alpha channel
2. OpenCV图像转换为ROS消息的函数
在CvImage类中执行的OpenCV图像转换为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;};
该函数的输入有三个:标准消息包的头、图像编码和OpenCV源图像,使用例程如下:
cv::Mat image = cv::imread(......);sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
转载地址:http://eggv.baihongyu.com/