【ROS教程】如何发布和订阅压缩图像消息(CompressedImage)

文章目录

  • 使用 cv_bridge 发布/订阅压缩图像
  • 发送图像
  • 接收图像
  • 使用 opencv 手动发布/订阅
  • 发送图像
  • 接收图像
  • 使用 image_transport 将发送的图像转发为压缩图像
  • 效果展示

  • 使用 cv_bridge 发布/订阅压缩图像

    参考 cv_bridge 文档

    发送图像

    from sensor_msgs.msg import CompressedImage
    from cv_bridge import CvBridge
    # 创建 publisher
    cimage_pub = rospy.Publisher("/image/compressed", CompressedImage, queue_size=1)
    # 创建并发送压缩图像消息
    compressed_msg = CvBridge().cv2_to_compressed_imgmsg(image, "jpg")
    compressed_msg.header.stamp = rospy.Time.now()
    cimage_pub.publish(compressed_msg)
    

    其中 “jpg” 表示将图像压缩的目标格式,还有很多其他参数可选,如下所示
    但亲测 “jpg” 压缩比最大,图像传输占用的带宽最少

    bmp, dib
    jpeg, jpg, jpe
    jp2
    png
    pbm, pgm, ppm
    sr, ras
    tiff, tif
    

    接收图像

    from sensor_msgs.msg import CompressedImage
    from cv_bridge import CvBridge
    # 定义回调函数
    def cvbridge_callback(self, data):
        image = CvBridge().compressed_imgmsg_to_cv2(data, "bgr8")
    # 创建 subscriber
    rospy.Subscriber("/image/compressed", CompressedImage, cvbridge_callback, queue_size=1)
    

    其中 “bgr8” 表示将图像解析为 “bgr8” 格式,也是 opencv 默认的图像格式

    使用 opencv 手动发布/订阅

    参考 rospy wiki 教程
    参考 opencv 中 imencode 与 imdecode 文档说明

    发送图像

    from sensor_msgs.msg import CompressedImage
    import cv2
    import numpy as np
    # 创建 publisher
    cimage_pub = rospy.Publisher("/image/compressed", CompressedImage, queue_size=1)
    # 创建并发送压缩图像消息
    compressed_msg = CompressedImage()
    compressed_msg.header.stamp = rospy.Time.now()
    compressed_msg.format = "jpg"
    compressed_msg.data = np.array(cv2.imencode('.jpg', image)[1]).tobytes()
    cimage_pub.publish(compressed_msg)
    

    “jpg” 作用同上,需要手动设置 compressed_msg.format 表示为压缩格式(但亲测不设置对 rqt 显示和解压缩也没啥影响)
    此外,可以手动调节压缩图像的相关参数,如调整 jpg 图像压缩质量为 5(默认为 95)

    # 创建并发送压缩图像消息
    compressed_msg = CompressedImage()
    compressed_msg.header.stamp = rospy.Time.now()
    compressed_msg.format = "jpg"
    compressed_msg.data = np.array(cv2.imencode('.jpg', image, [cv2.IMWRITE_JPEG_QUALITY, 5])[1]).tobytes()
    cimage_pub.publish(compressed_msg)
    

    接收图像

    from sensor_msgs.msg import CompressedImage
    import cv2
    import numpy as np
    # 定义回调函数
    def cv2_callback(self, data):
        image = np.frombuffer(data.data, np.uint8)
        image = cv2.imdecode(image, cv2.IMREAD_COLOR)
    # 创建 subscriber
    rospy.Subscriber("/image/compressed", CompressedImage, cv2_callback, queue_size=1)
    

    使用 image_transport 将发送的图像转发为压缩图像

    参考 image_transport wiki
    如果不想写程序对图像进行处理,可以使用 image_transport 包的命令行工具来将 Image 消息转发为 CompressedImage 消息

    rosrun image_transport republish raw in:=/image compressed out:=/image
    

    该节点会自动订阅/image话题下的Image消息,并将CompressedImage格式的消息发送到/image/compressed话题下
    压缩的相关参数可以通过 rqt 工具箱里的 Dynamic Reconfigure 工具箱进行调整:

    Dynamic Reconfigure

    效果展示

    rqt
    如果 rqt 可视化过程中显示错误:Unable to load plugin for transport ‘cvbridge_compressed’
    可参考 【ROS】rqt显示压缩图像话题报错:Unable to load plugin for transport ‘cvbridge_compressed’

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【ROS教程】如何发布和订阅压缩图像消息(CompressedImage)

    发表回复