描述:本教程介绍如何使用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图像编码:
对于流行的图像编码,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)
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图像的编码。如果您已成功将图像转换为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