订阅相机话题,Image消息如何制作成视频
-
此回复已被删除! -
在你的ROS 2订阅者代码中,有几个问题和潜在的改进点。首先,让我们逐一解决这些问题,以确保你能够正确地从ROS 2话题中接收图像并生成视频。
1. 初始化视频写入器时使用的帧尺寸问题
在你的订阅者代码中,你硬编码了视频帧的宽度和高度为480x480,但这可能并不匹配从摄像头获取的实际帧尺寸。这会导致视频写入失败或视频显示不正确。你应该从接收到的图像消息中获取实际的宽度和高度。
2. 帧速率匹配
你设置了视频帧速率为30fps,但如果发布者发布的速率不匹配,这可能导致视频同步问题。虽然这通常不会导致错误,但最好确保它们是匹配的,或者至少理解它们之间的差异。
3. 确保资源正确释放
在ROS 2节点中,你需要确保在节点关闭时正确释放所有资源,包括视频写入器和OpenCV窗口。
4. 错误处理和日志记录
增加错误处理和日志记录可以帮助调试和运行时监控。
修改后的订阅者代码
下面是根据上述建议修改后的订阅者代码:
import cv2 from cv_bridge import CvBridge from rclpy.node import Node from sensor_msgs.msg import Image class ImageSubscriber(Node): def __init__(self, node_name): super().__init__(node_name) self.subscriber_ = self.create_subscription(Image, 'image_raw', self.listener_callback, 10) self.cv_bridge = CvBridge() self.video_writer = None # 初始化视频写入器将在接收到第一帧时进行 self.first_frame_received = False def listener_callback(self, data): try: image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8') if not self.first_frame_received: # 设置视频写入器,使用接收到的第一帧的尺寸 height, width = image.shape[:2] fourcc = cv2.VideoWriter_fourcc(*'XVID') fps = 30 # 假设与发布者发布的速率一致,或根据需要调整 self.video_writer = cv2.VideoWriter('output_video.avi', fourcc, fps, (width, height)) self.first_frame_received = True if rclpy.ok(): cv2.imshow("Received Image", image) self.video_writer.write(image) cv2.waitKey(1) # 确保与fps相匹配的时间间隔 except Exception as e: self.get_logger().error(f"Error processing image: {e}") def on_shutdown(self): self.get_logger().info("Shutting down subscriber...") if self.video_writer: self.video_writer.release() cv2.destroyAllWindows() # 确保在节点关闭时调用on_shutdown def main(args=None): rclpy.init(args=args) node = ImageSubscriber('image_subscriber') rclpy.spin(node) node.on_shutdown() # 手动调用以确保资源释放 rclpy.shutdown() if __name__ == '__main__': main()
注意事项
- 确保ROS 2节点正确关闭(例如,使用
Ctrl+C
停止脚本),以便触发on_shutdown
方法。 - 根据你的具体需求调整fps和编码格式。
- 如果发布者和订阅者运行在不同的机器上,确保网络延迟和带宽不会影响视频流的实时性。
希望这些修改能帮助你解决问题!如果还有其他问题,欢迎继续提问。
以上为生成回答,仅供参考~
- 确保ROS 2节点正确关闭(例如,使用