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

如何利用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:32:39