描述:本教程介绍如何使用cv_bridge将ROS图像转换为OpenCV图像,反之亦然,从而实现ROS和OpenCV的交互。 包括一个示例节点,可用作您自己节点的模板。
1.概念
ROS以其自己的sensor_msgs/Image消息格式发布图像,但许多用户会希望将图像与OpenCV结合使用。 CvBridge是一个ROS库,提供ROS和OpenCV之间的接口。 可以在vision_opencvv堆栈的cv_bridge软件包中找到CvBridge。
在本教程中,您将学习如何编写一个节点,这个节点可以通过使用CvBridge将ROS图像转换为OpenCV cv::Matt格式。同时,您还将学习如何将OpenCV图像转换为ROS格式,以便通过ROS发布图像消息。
2.将ROS图像消息转换为OpenCV图像
要将ROS图像消息转换为cv :: Mat,模块cv_bridge.CvBridge提供以下功能:
cv_image = bridge.imgmsg_to_cv2(image_message, desired_encoding="passthrough")
输入是图像消息,以及可选的编码。 编码引用目标cv :: Mat图像。如果给出默认值“passthrough”,则目标图像编码将与图像消息编码相同。 图像编码可以是以下任何一种OpenCV图像编码:
- 8UC[1-4]
- 8SC[1-4]
- 16UC[1-4]
- 16SC[1-4]
- 32SC[1-4]
- 32FC[1-4]
- 64FC[1-4]
对于流行的图像编码,CvBridge将根据需要选择进行颜色或像素深度转换。 要使用此功能,请指定编码为以下字符串之一:
mono8: CV_8UC1, grayscale image
mono16: CV_16UC1, 16-bit grayscale image
bgr8: CV_8UC3, color image with blue-green-red color order
rgb8: CV_8UC3, color image with red-green-blue color order
bgra8: CV_8UC4, BGR color image with an alpha channel
rgba8: CV_8UC4, RGB color image with an alpha channel
3.将OpenCV图像转换为ROS图像消息
将cv :: Mat转换为ROS图像消息,CvBridge提供以下功能:
image_message = cv2_to_imgmsg(cv_image, encoding="passthrough")
这种情况下,“编码”的使用稍微复杂一些。 它和以前一样,参考cv :: Mat。 但是,cv2_to_imgmsg()不会为您执行任何转换(而是使用CvtColor和ConvertScale)ROS图像消息必须始终具有与cv :: Mat相同数量的通道和像素深度。 然而,上面特别常用的图像格式(bgr8,rgb8等)会将信息插入到有关频道排序的图像消息中。 这样,未来的消费者就会知道他们收到的图像是RGB还是BGR。
4.一个ROS节点的例子
这里是一个监听ROS图像消息主题的节点,将图像转换为cv :: Mat,并在其上绘制一个圆圈并使用OpenCV显示图像。 该图像然后通过ROS重新发布。
在你的manifest(或者当您使用roscreate-pkg时),添加以下依赖项:
sensor_msgs opencv2 cv_bridge rospy std_msgs
#!/usr/bin/env python from __future__ import print_function import roslib roslib.load_manifest('my_package') import sys import rospy import cv2 from std_msgs.msg import String from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError class image_converter: def __init__(self): self.image_pub = rospy.Publisher("image_topic_2",Image) self.bridge = CvBridge() self.image_sub = rospy.Subscriber("image_topic",Image,self.callback) def callback(self,data): try: cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: print(e) (rows,cols,channels) = cv_image.shape if cols > 60 and rows > 60 : cv2.circle(cv_image, (50,50), 10, 255) cv2.imshow("Image window", cv_image) cv2.waitKey(3) try: self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8")) except CvBridgeError as e: print(e) def main(args): ic = image_converter() rospy.init_node('image_converter', anonymous=True) try: rospy.spin() except KeyboardInterrupt: print("Shutting down") cv2.destroyAllWindows() if __name__ == '__main__': main(sys.argv)
不要忘记chmod + x你的文件。
import sys
所有的OpenCV都包含在导入cv中。 在manifest中,为opencv2和cv_bridge添加依赖项。
from std_msgs.msg import String
CvBridge也存在于cv_bridge。
cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: print(e)将图像消息指针转换为OpenCV消息只需要调用函数imgmsg_to_cv2()。 这需要图像消息以及目标OpenCV图像的编码。
您应该始终将您的调用包装到imgmsg_to_cv2()以捕获转换错误。
要运行该节点,您需要一个图像流。 运行相机或播放包文件以生成图像流。 现在,您可以运行此节点,将图像流主题重新映射到“image_topic”。 例如,“/ camera / rgb / image_color”。
如果您已成功将图像转换为OpenCV格式,您将看到名为“image window”,并有圆圈的HighGui窗口
self.image_pub.publish(self.bridge.cv2_to_imgmsg(cv_image, "bgr8")) except CvBridgeError as e: print(e)
使用编码为“bgr8”的cv2_to_imgmsg()将编辑后的图像转换回ROS图像消息格式,以便将来的订户知道颜色顺序。
您可以使用rostopic或通过使用image_view.查看图像来查看节点是否正确地通过ros发布图像。
参考网址:Tutorials