译:ROS和Openv之间的图像转换(Python)

描述:本教程介绍如何使用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

请注意,mono8和bgr8是大多数OpenCV函数预期的两种图像编码。

3.将OpenCV图像转换为ROS图像消息

将cv :: Mat转换为ROS图像消息,CvBridge提供以下功能:

image_message = cv2_to_imgmsg(cv_image, encoding="passthrough")

这种情况下,“编码”的使用稍微复杂一些。 它和以前一样,参考cv :: Mat。 但是,cv2_to_imgmsg()不会为您执行任何转换(而是使用CvtColorConvertScale)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

猜你喜欢

转载自blog.csdn.net/weixin_40863346/article/details/80430251
今日推荐