Grabbed snapshots are not the last image

Dear CVB team,

I’m facing a problem with images acquired sparsely in time on a CVB connected camera. To be precise the application handles TCP requests. For each request it grabs one image from the camera and tags it with an ID (extracted from the request).

This looks like a quite simple task but we noticed that the call to stream.wait_for(1000) does not gives the latest image form the stream but an old one the one that should have been returned 2 or 3 requests before and this is just not possible for us as the tag should be applied onto the right image.

We temporarily fixed the issue by calling several time stream.wait_for(1000) for each image grabbing keeping only the last one but it is a quite awful fix, isn’t it? Nevertheless if I believe the documentation, the wait_for(timeout) is intended to send the “next” frame an not “one of the past ones”. Is this issue potentially linked to a missed configuration of the camera that we are not using to stream images but mor to take a snapshot at a random time?

We tried to use the get_snapshot() instead of wait_for(timeout) as this function is told to provide one image for the stream but it always returns an error (WaitError if I’m not wrong). do you have an example of using this function in the python API to provide me?

Here are some configuration data:
Arch intel
OS Ubuntu 18.04
python version 3.6.5
CVB 13.03.003
Camera Jaï GO 5100 USB
Std::DeviceVendorName = “JAI Corporation”
Std::DeviceModelName = “GO-5100M-USB”
Std::DeviceManufacturerInfo = “See the possibilities”
Std::DeviceVersion = “”
Std::DeviceFirmwareVersion = “”
Cust::DeviceFpgaVersion = “”

Best regards

Hi @obrousse ,

wait_for returns the next ringbuffer image. So when you have set the buffer count to 10 and start the acquisition, all 10 buffers will be filled. The next wait() call returns then the oldest image from the ringbuffer which would be the next one that was recorded by the camera. The intended use is for continuous acquisition where the ringbuffer never runs full because the images are processed as fast as or even faster as the buffer is filled.

As you already found out, a good solution in your case would indeed be the get_snapshot() function. When a snapshot is taken, the stream is started, an image is waited for and the stream is stopped again. I would assume that you still manually start the stream and thus the get_snapshot() fails to start the stream again. So you only would need to call stream.get_snapshot() Does that help?

Best regards

Thanks a lot!

I actually have the stream started at the application initialization and stopped when the application ends or is terminated/killed etc. So this must be the cause of get_snapshot failures. I will have to try that solution of not starting the stream and use get_snapshot to measure the system reactivity because I’m afraid that it will take some more time to start/grab/stop than to read the ring buffer. As we get one request every 2 seconds coarsely and a time budget quite reserved for further processing onto the image I will have to be sure that it won’t mess up with the time constraints.

Do you think that we can safely set the ring buffer to 2 and then only call twice wait_for() to ensure that the data is the correct one while keeping our time schedule as it is for now?

Once more thank you for the explanations on the actual wait_for operation mode as well as for the get_snapshot usage that makes sense - but may be more documented or illustrated with examples in CVBpy to avoid this kind of “fake issues” I faced.

Best regards

You can try the lower buffer count and test if that works better for you then the snap. It is also possible to change the lock_mode of the ringbuffer to cvb.RingBufferLockMode.On, start the acquisition and manually call _unlock _ in a loop, so all acquired images are overridden. When you need the image you would then call wait first and resume calling unlock on the buffer when the image is not needed any more. See
Lockmode On would mean “manually release buffer”, Off is auto override (also when you are working on the image) and default is auto which locks the images in the buffer until you get an image with wait and discard the image again. This would then unlock the buffer for new acquisition.

You are right, that the functionality could be described more in the python wrappers. But please also keep in mind, that the python wrappers are still quite new. We are currently working on an updated and more streamlined documentation.

Thanks for the reply and those interesting alternatives, I’ll investigate and select the one that best suits our constraints.

You did a great job with the python binding and explaining to me how I can get deeper in this wrapper.

Once again thank you for the help. I’ll update the post with the retained solution.

Best regards