ROS是机器人领域中比较受到关注的一种系统,它的应用比较方便而且有许多的工具比如传感器驱动包可以直接使用。但是ROS对于传感器数据有自己的格式和规范。而在OpenCV中,图像是以Mat矩阵的形式存储的,这与ROS定义的图像消息的格式有一定的区别,所以我们需要利用cv_bridge将这两种不相同的格式联系起来,如下图所示。
本次笔记大部分参考的是ROS官网给出的一些的定义和技术细节,网址如下:
http://wiki.ros.org/cv_bridge
1. ROS图像消息转换为OpenCV图像的函数
当cv_bridge将ROS的图像消息转换为OpenCV图像格式时都是通过CvImage类实现的。一般来说,cv_bridge提供了两种方式转换为CvImage类,分别为复制(copy)和共享(share)。
上面是这两类方式实现的函数对应为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中常用的编码有以下那么几种:
|
2. OpenCV图像转换为ROS消息的函数
在CvImage类中执行的OpenCV图像转换为ROS消息的成员函数为 toImageMsg(),其源码中的定义如下所示:该函数的输入有三个:标准消息包的头、图像编码和OpenCV源图像,使用例程如下:
cv::Mat image = cv::imread(......); sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg(); |