Closed i-jey closed 1 year ago
Corrupted frame even FrameStatus=Complete sounds strange indeed. Does it happen in VimbaViewer too? Assuming a performance issue I'd suggest to slow down a bit, slightly decrease DeviceLinkThroughputLimit. If the Alvium 1800 U-319m is still suspected please check for a firmware update first of all: https://www.alliedvision.com/en/support/firmware-downloads/
A resolution!
This is my fault, this problematic behaviour, and a guard against it, is laid out clearly in the multithreading_opencv.py
example (here).
The relevant section is here:
def __call__(self, cam: Camera, frame: Frame):
# This method is executed within VimbaC context. All incoming frames
# are reused for later frame acquisition. If a frame shall be queued, the
# frame must be copied and the copy must be sent, otherwise the acquired
# frame will be overridden as soon as the frame is reused.
if frame.get_status() == FrameStatus.Complete:
if not self.frame_queue.full():
frame_cpy = copy.deepcopy(frame)
try_put_frame(self.frame_queue, cam, frame_cpy)
For my code above, I simply updated the _frame_handler
to the following:
def _frame_handler(self, cam, frame):
try:
self.queue.get_nowait()
except queue.Empty:
pass
if frame.get_status() == vimba.FrameStatus.Complete:
frame_deep_copy = np.copy(frame.as_numpy_ndarray()[:, :, 0])
self.queue.put(frame_deep_copy)
cam.queue_frame(frame)
Because the frame object is reused, multithreading (which is how I was dealing with frames in my application) runs the risk of having the image data become partially overwritten as you are still dealing with it. Creating a deep copy of the frame ensures that the camera cannot overwrite it.
The DeviceLinkThroughput
parameter does not need to be changed!
Cheers.
Acquiring images asynchronously, I'm running into an issue where frame data appears to be mixed up with subsequent/previous frames. In the example photos below, there are parts of these frames which appear to come from the subsequent frame. This issue appears to happen the most when there are bright/dark transitions between frames. Unfortunately for our eventual use case, that is going to be nearly every frame!
I'm doing a check for the frame status to ensure it's complete - so I am a little puzzled as to what's causing this behaviour. Fyi, this is an AVT Alvium 1800 U-319m mono bareboard connected to a Raspberry Pi 4 over USB3.0.
Initial frame:
Frame with patch:
Last frame:
I've opted to use the AVT camera w/o a context manager as it fits our design case better (we are use a couple of different models of cameras, all of which need to have the same API wrapped around so that they can be drop-in replacements).
Here's the
_frame_handler
:and here's the rest of the "
AVTCamera
" wrapper:Any insight or advice would be greatly appreciated! I worry I've overlooked something simple while circumventing the original context-manager use-case.
I saw this issue on Pymba (a Python API predating AVT's official API) which seemed relevant, however the proposed solution at the end of that thread was simply to ignore frames with
frame.data.receiveStatus == -1
, which I believe is whatframe.get_status() == vimba.FrameStatus.Complete
should be doing anyway?