G2Wait does not change image data

I’ve encountered a strange effect when acquiring images and accessing the pixel values. It seems that I have to call G2Wait three times before I actually get a new image. I have the following code:


IMG img = nullptr;
LoadImageFile("GenICam.vin", img);

void* pBase = nullptr;
PVPAT vpa = nullptr;
GetImageVPA(img, 0, pBase, &vpa);

// all pixels are null/black - default value? 

G2Grab(img);

G2Wait(img); // first new image - pixel values changed
G2Wait(img); // no new image - pixel values stay unchanged
G2Wait(img); // no new image - pixel values stay unchanged
G2Wait(img); // new image - pixel values changed
...

I omitted the return codes in the snippet above, but I checked. All calls return without an error code.
Any advice on that issue?

What was the error code returned by the G2Wait calls?

Ok, to be more precise the term:

G2Wait() == CVC_ERROR(CVC_E_OK)

always evaluates to true, so I conclude there is no error?

No. Generally: If a function in Common Vision Blox returns a value of type cvbres_t in the C interface (in C# and Delphi this is mapped to an integer) then by convention a value of 0 (== CVC_ERROR(CVC_E_OK)) indicates success, < 0 indicates an unrecoverable error (i.e. the function did not do what you’d expect it to do) and > 0 means that the function did what it is expected to do, but something might be wrong (effectively a warning, but this condition generally only occurs with very few functions).

So the cause for the old images occurring is not something like e.g. a timeout during acquisition (in that case, G2Wait would return CVC_ERROR(CVC_E_TIMEOUT) which is < 0). Can you use G2GetGrabStatus to find out whether there is a transfer problem? (look for the values returned with G2Info_NumBuffersLost, G2Info_NumBuffersLostLocked, G2Info_NumBuffersCorrupOnDelivery - do these increase over time?)

If you are using a GigE vision camera, you might also want to check whether enabling Packet Resend would change what you’re seeing (see here).

Now I’m confused :confused:,
I do not get the difference between “no error” and “success” - let a side the possibility of warnings. Isn’t is safe to assume that there was no error inside CVB if a function returns 0?
Of course that does not prevent me from using the functions in a wrong way.

… back to the topic …
So I checked with G2GetGrabStatus:

  • G2Info_NumBuffersLost - is 0 all the time
  • G2Info_NumBuffersLostLocked - is 0 all the time
  • G2Info_NumBuffersCorrupOnDelivery - is 0 all the time

Additionally I checked GRAB_INFO_NUMBER_IMAGES_AQCUIRED and it increases with every call to G2Wait. That looks fine to me.
Furthermore I do not see any problems with the acquisition if I use GenICam Browser or the Common Vision Blox viewer. However, I’m still stuck with pixel access :worried: .

You right, it does not sound like an issue related to acquisition.

The issue might be caused by your code in the first post. How exactly do you verify if the image contend has changed?
Your code does not make this absolutely clear? However, I assume you always use the same pBase and vpa to access the pixel data. If so, this explains your observations.

Unfortunately an IMG is often referred to as image, whereas it is usually much more than that. In order to understand what an IMG is you can roughly distinguish between two cases:

Plain File Case

You get a handle by loading a image file (*.bmp, *.png etc.) from disc. Therefore you may access the raw data at any time using GetImageVPA. In this case the term “image” pretty much covers it.

Device Case

You get a handle by loading a VIN driver (*.vin). In this case the handle represents a device. This in turn makes pixel access more complex. As e.g device may stream a series of images (not just one) to the host. In order to handle such streaming a set of buffers is attached to each device (IMG). However, GetImageVPA only refers to the current buffer and this will change with every call to G2Wait.

Therefore change your code like this:

IMG img = nullptr;
LoadImageFile("GenICam.vin", img);

void* pBase = nullptr;
PVPAT vpa = nullptr;


G2Grab(img);

G2Wait(img); // current buffer index is 0
GetImageVPA(img, 0, pBase, &vpa);
G2Wait(img); // current buffer index is 1
GetImageVPA(img, 0, pBase, &vpa);
G2Wait(img); // current buffer index 2
GetImageVPA(img, 0, pBase, &vpa);
G2Wait(img); // current buffer is 0
...

If you look at the values of pBase you will see them change after each GetImageVPAT.

By default the GenIcam.ini defines NumBuffer=3 so buffer 0 is reused after three calls to G2Wait.

2 Likes

Thank you very much, works like expected. It’ actually quite easy once I did it right.:grin:
By the way I would have excepted a hint to this “current buffer” changing stuff in the doc for G2Wait.