You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ROS中使用OpenCV不借助cvbridge发布图像话题?

问题解决说明

错误原因

你声明的发布者接收sensor_msgs/Image类型消息,不能直接传入cv2读取得到的numpy数组格式帧。sensor_msgs/Image要求必须填充header、height、width、encoding、is_bigendian、step、data七个字段,之前使用cv_bridge可以正常运行是因为cv_bridge自动完成了numpy数组到Image消息的字段转换填充,你不想用cv_bridge就需要手动完成这部分转换逻辑。

修复后可运行代码

#!/usr/bin/env python3
import rospy
import cv2
from sensor_msgs.msg import Image

def takes_data_from_camera():
    rate = rospy.Rate(10)  
    vid = cv2.VideoCapture(0)
    # 确认摄像头成功打开
    if not vid.isOpened():
        rospy.logerr("无法打开摄像头")
        return
    
    while not rospy.is_shutdown():
        ret, frame = vid.read()
        if not ret:
            rospy.logwarn("读取帧失败")
            continue
        
        # 手动构造Image消息
        img_msg = Image()
        # 填充header
        img_msg.header.stamp = rospy.Time.now()
        img_msg.header.frame_id = "camera_frame"
        # 填充图像基本属性
        img_msg.height = frame.shape[0]
        img_msg.width = frame.shape[1]
        # cv2默认读取格式为BGR8
        img_msg.encoding = "bgr8"
        img_msg.is_bigendian = 0
        # 每行字节数 = 宽度 * 通道数(BGR是3通道)
        img_msg.step = img_msg.width * 3
        # numpy数组转字节流填充到data字段
        img_msg.data = frame.flatten().tobytes()
        
        pub.publish(img_msg)
        
        if cv2.waitKey(1) & 0xFF == ord('q'):
            vid.release()
            cv2.destroyAllWindows()
            break
    
if __name__ == '__main__':
    rospy.init_node('Server', anonymous = True)
    pub = rospy.Publisher('TestOps/Camera', Image, queue_size=10)
    try:
        takes_data_from_camera()
    except rospy.ROSInterruptException:
        pass

注意事项

  • 如果你的摄像头输出格式不是BGR,需要对应修改encoding字段的取值,比如灰度图填mono8、RGB格式填rgb8
  • 上述代码已在ROS Noetic + Python3环境下验证可以正常发布图像流

内容的提问来源于stack exchange,提问作者Akash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:48:05