How to acquiring only the latest image from the buffer

Hi,

I am working with 4 cameras that are being triggered from PLC every 0.3-0.6 sec depending on how we set it. Sometimes 2 frames are grabbed and I when I use stream.wait() I receive the second photo form the last trigger and not the current photo. The result is that 2 cameras show latest photo and 2 might have the old one.

Can I somehow clear the buffer on ensure that I am getting the latest photo when using stream.wait()? I was trying to use ring_buffer.lock_mode to lock the buffer and access the last buffer photo but I have no idea how to access the latest photo and when to call stream.wait() in that situation.

I was also trying the Acquisition mode as single frame but I don’t know how to exactly use it and if it is even a way to go.

Or maybe I can manually somehow clear the camera buffer?

Thanks!
Piotr

Hi @piotrM,

sorry for the late reply. This function should do what you want:

import typing
import cvb

def wait_for_newest(stream: cvb.Stream, time_span: typing.Optional[int] = None) -> typing.Tuple[cvb.StreamImage, cvb.WaitStatus]:
    while True:
        image, status = stream.wait() if time_span is None else stream.wait_for(time_span)
        num_pending = stream.statistics[cvb.StreamInfo.NumBuffersPending]
        if status is not cvb.WaitStatus.Ok or num_pending == 0:
            return image, status

So you could use this either like wait_for_newest(device.stream) or add it to the methods of your current stream (assuming your cvb.Device is device) via Python’s descriptor protocol:

device.stream.wait_for_newest = wait_for_newest.__get__(device.stream)

Then you can call device.stream.wait_for_newest() directly. But keep in mind that you have to do the assignment for every new cvb.Stream object you create via cvb.DeviceFactory.open

This is for usage with lockmode auto, though. Which is perfect for the use case you have in mind. It works, because stream.wait returns immediately if there is still an image in the ring buffer (num buffers pending > 0).

Attention:
You still must be, or make sure that you are in sync with your triggers. Not that you get in an overlap scenario where you get 4 images of the current batch and one from the next batch. Or what happens if a frame of one of the cameras is dropped due to transfer issues?

To prevent something like that you need to inspect the time stamps: image.raw_timestamp. It is called raw as this is just a number. The meaning depends on the hardware used… For more in depth description on transfer monitoring look at post here:

2 Likes

Thanks a lot! Sorry for a late response. I will try this code out and let you know how it went.