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

如何使用Vimba Python异步抓取Allied Vision相机的帧并按需调用?

实现Vimba Python异步抓帧并通过队列按需获取

要实现异步抓帧并将帧存入队列按需获取,核心是利用Vimba的帧回调机制,配合线程安全的队列来缓存处理后的帧。以下是完整的实现方案:

关键思路

  • 注册回调函数:相机每抓取一帧就触发该函数,在回调中完成帧转numpy数组、存入队列的操作,同时必须将帧归还给相机的帧池(避免内存耗尽)。
  • 使用线程安全队列:由于回调函数运行在Vimba的内部线程中,主线程获取帧时需要线程安全的容器(比如queue.Queue)。
  • 按需消费:主线程可以从队列中阻塞/非阻塞获取帧,处理逻辑和抓帧逻辑完全解耦。

完整代码示例

import vimba
import numpy as np
import queue
import time

# 初始化线程安全队列,设置最大容量避免内存溢出
frame_queue = queue.Queue(maxsize=20)

def frame_callback(frame: vimba.Frame):
    """相机帧回调函数:处理帧并存入队列"""
    try:
        # 将帧转换为numpy数组,注意这里要复制数组,否则后续帧会覆盖buffer内容
        img = np.ndarray(
            buffer=frame._buffer,
            dtype=np.uint16,
            shape=(frame.height, frame.width)
        ).copy()
        
        # 将处理后的帧存入队列,若队列满则阻塞等待
        frame_queue.put(img)
        
    finally:
        # 必须将帧归还给相机帧池,否则相机将无法继续抓取新帧
        frame.queue()

def main():
    with vimba.Vimba.get_instance() as vimba_instance:
        # 枚举并打开相机(这里默认取第一个相机,可根据需要修改)
        cams = vimba_instance.get_all_cameras()
        if not cams:
            print("未找到相机")
            return
            
        with cams[0] as cam:
            # 配置相机参数(根据你的需求调整,比如像素格式、帧率等)
            cam.set_pixel_format(vimba.PixelFormat.Mono16)
            # 设置抓帧模式为异步,buffer_count为预分配的帧缓存数量
            cam.start_streaming(callback=frame_callback, buffer_count=10)
            
            try:
                # 按需获取帧示例:这里模拟获取10帧并处理
                for _ in range(10):
                    # 阻塞等待队列中有帧
                    img = frame_queue.get()
                    # 这里添加你的帧处理逻辑
                    print(f"获取到帧,尺寸:{img.shape}")
                    # 标记任务完成(若使用队列的join()方法则需要)
                    frame_queue.task_done()
                    
                    # 模拟处理耗时
                    time.sleep(0.1)
                    
            finally:
                # 停止流传输,清理资源
                cam.stop_streaming()
                
        # 等待队列中所有帧处理完成(可选)
        frame_queue.join()

if __name__ == "__main__":
    main()

重要注意事项

  • 必须归还帧:回调函数的finally块中一定要调用frame.queue(),否则相机的帧池会被耗尽,导致无法继续抓帧。
  • 数组复制:转换numpy数组时要调用.copy(),因为Vimba的帧buffer是复用的,若不复制,后续新帧会覆盖当前数组的内容。
  • 队列容量:设置maxsize避免队列无限增长导致内存占用过高,当队列满时,frame_queue.put()会阻塞,直到队列有空闲位置。
  • 相机参数匹配:根据相机型号和需求调整像素格式,确保和转换numpy数组时的dtype对应(比如Mono16对应np.uint16)。

内容的提问来源于stack exchange,提问作者Eloi Canals Pascual

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:30:42