如何利用rospy.Subscriber获取间隔3秒的两张不同图像
你当前代码的核心问题在于对ROS订阅器的异步机制理解有误,加上不合理的文件中转方式,导致两次获取的图像相同。具体问题和修复方案如下:
问题分析
- 订阅器异步特性:ROS订阅器的回调函数是异步执行的,
rate.sleep()只是让主线程暂停,但订阅器会持续接收消息队列中的数据,两个订阅器可能同时拿到队列里的同一张旧图像。 - 未初始化CvBridge:代码里
bridge1和bridge变量没有创建实例,运行时会直接报错。 - 文件中转的风险:用文件保存再读取的方式,可能因为IO速度跟不上,导致两次读取到同一张未更新的图片。
修复方案
改用单订阅器+全局变量存储图像的方式,先捕获第一张图像,等待3秒后再捕获第二张,完全避免文件中转的问题:
import cv2 import numpy as np import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError # 全局变量存储最新图像 latest_img = None bridge = CvBridge() # 初始化CvBridge实例 def cam_callback(msg): global latest_img try: # 将ROS图像消息转为OpenCV格式 latest_img = bridge.imgmsg_to_cv2(msg, "bgr8") except CvBridgeError as e: print(e) if __name__ == "__main__": rospy.init_node("orientation_feature_detection_py") image_topic = '/s500/usb_cam/image_raw' # 订阅图像话题,持续更新最新图像 rospy.Subscriber(image_topic, Image, cam_callback) # 等待获取第一张有效图像 while latest_img is None and not rospy.is_shutdown(): rospy.sleep(0.1) img1 = latest_img.copy() # 复制图像到本地变量,避免后续被覆盖 # 等待3秒 rospy.sleep(3) # 确保获取到新的图像(可选:如果担心3秒内没有新图像,可以加循环等待) while latest_img is None or np.array_equal(latest_img, img1) and not rospy.is_shutdown(): rospy.sleep(0.1) img2 = latest_img.copy() # 现在可以使用img1和img2进行姿态对比 print("成功获取间隔3秒的两张图像") # 示例:显示图像 cv2.imshow("Image 1", img1) cv2.imshow("Image 2", img2) cv2.waitKey(0) cv2.destroyAllWindows()
关键改进点
- 用全局变量
latest_img实时保存最新图像,避免文件IO的同步问题。 - 先等待获取第一张有效图像后,再等待3秒获取第二张,确保时间间隔。
- 复制图像到本地变量(
img1 = latest_img.copy()),防止后续回调更新latest_img时覆盖之前的图像。 - 可选的二次校验:等待3秒后,检查新图像是否和第一张相同,避免因为相机帧率低导致拿到同一张图。
内容的提问来源于stack exchange,提问作者Aviationman
相关产品推荐
相关产品推荐

