VimbaPython
VimbaPython copied to clipboard
How to use asynchronous capture with multiple cameras?
I'm trying to stream frames from two cameras at the same time (Allied Vision 1800 U-2050c, Allied Vision 1800 U-2460c) using the following code:
from vimba import Camera, Frame, FrameStatus, PixelFormat, Vimba
import time
import threading
def setup_camera(cam: Camera) -> None:
cam.set_pixel_format(PixelFormat.Mono8)
cam.AcquisitionMode.set("Continuous")
cam.BinningVertical.set(1)
cam.BinningHorizontal.set(1)
cam.Width.set(5328)
cam.Height.set(3672)
cam.ExposureAutoMin.set(1000.0)
cam.ExposureAutoMax.set(20000.0)
cam.ExposureTime.set(20000.0)
cam.Gain.set(10.0)
cam.AcquisitionFrameRateEnable.set(True)
cam.AcquisitionFrameRate.set(1)
class Handler:
def __init__(self, idx: int):
self._idx = idx
def __call__(self, camera: Camera, frame: Frame) -> None:
if frame.get_status() == FrameStatus.Complete:
print(f"{time.monotonic()} - cam #{self._idx}: complete frame")
else:
print(f"{time.monotonic()} - cam #{self._idx}: failed frame: {frame}")
camera.queue_frame(frame)
stop_running = False
def capture_thread(idx, cam):
global stop_running
setup_camera(cam)
handler = Handler(idx)
cam.start_streaming(handler=handler, buffer_count=2)
while not stop_running:
time.sleep(1.0)
cam.stop_streaming()
with Vimba.get_instance() as vimba:
cameras = vimba.get_all_cameras()
with cameras[0] as cam0:
with cameras[1] as cam1:
t0 = threading.Thread(target=capture_thread, args=(0, cam0))
t1 = threading.Thread(target=capture_thread, args=(1, cam1))
t0.start()
t1.start()
input("press enter to stop\n")
stop_running = True
t0.join()
t1.join()
I would expect the handlers in both threads to be regularly called using a frame from the associated camera, but in practice only the handler for the first camera (with index 0) is actually called.
Sample output:
press enter to stop
1213137.914160055 - cam #0: complete frame
1213138.914284494 - cam #0: complete frame
1213141.914462255 - cam #0: complete frame
1213144.914603388 - cam #0: complete frame
1213145.91475032 - cam #0: complete frame
1213148.914914694 - cam #0: complete frame
...
If I change the two binning values to 2 then it does work:
press enter to stop
1213817.792815084 - cam #1: complete frame
1213818.743061794 - cam #0: complete frame
1213818.792745757 - cam #1: complete frame
1213819.74312082 - cam #0: complete frame
1213819.792785887 - cam #1: complete frame
...
The change in behavior based on the binning value would suggest a problem with bandwidth, but I find it hard to believe that I would be running into bandwidth problems at a frame rate of 1 with monochrome images.
What am I doing wrong? How do I capture full resolution frames from both cameras?
Thank you for generating this issue. We recommend our Multithreading example for mutli cameras. Please find them in the example folder.
For future reference, my colleague @OvervCW got this to work by:
- Increasing usb-fs buffer size by a lot (see https://china.alliedvision.com/fileadmin/content/documents/products/cameras/various/appnote/USB/USB-Camera-Handling-Linux-Application-Note.pdf)
- Making sure that the frame handler function returns as quickly as possible. So by putting the image onto a queue to be processed by another process, without blocking when the queue is full.