如何在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
相关产品推荐
相关产品推荐

