Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

IMAQ Particle Analysis (for one) seems to return cached results for different image data

Perfect, thanks!

 

I was able to reproduce the problem here. I also saw that touching the pixel data via an EDVR/In-place-element structure shows the same issue. I suspect that there is something like you suspected that the Particle Analysis VIs are storing some sort of cached data on the image structure itself that is not being invalidated by the Map pixel and EDVR access. Changing the connectivity input parameter between the two analysis VIs seems to cause it to not use this cached data either.

 

I have opened internal CAR 543120 for tracking this issue. For now, it seems like there are workarounds you could apply that cause the cached data to be invalidated without actually modifying the data.

 

Message 11 of 18
(2,353 Views)

Thank you, BlueCheese, for confirming and reporting the issue. I can live with the workarounds, let's just hope the particle analysis functions are the exceptions and similar behaviour isn't waiting to emerge anywhere else.

0 Kudos
Message 12 of 18
(2,345 Views)

It is a fairly general failure (that Unmap doesn't clear the proper flag), but I'm not sure how many function in Vision actually hit all the requirements in order to get these types of failures. N

 

ote that your example code would still need a fix on your end to call Unmap after you have modified the pixel data in order to signal that the data is not going to continue to be changed behind the scenes (and potentially to allow the image buffer memory to be free'd -- I can't recall if the current Mapimplementation pins the memory or not).

0 Kudos
Message 13 of 18
(2,341 Views)

Now hold your horses wait a minute etc. What am I missing here, is the infamous "Unmap Pixel Pointer" related to this and actually supposed to be used? Now I do remember a while ago when I started combining IMAQ in LabVIEW with external code I was a bit puzzled by the unmap, and we've all probably seen Andrey_Dmitriev's post about it. At the time I ran a lot of tests and simply decided to ignore and drop it with a shrug—the overhead of the map-node-unmap was deterring enough in the high performance context (that often is the main reason for the external code in the first place). I tried now searching for more info again but I couldn't find any. Could you enlighten us about it?

0 Kudos
Message 14 of 18
(2,332 Views)

You are correct that today Unmap really does nothing of consequence. The whole reason it exists is that the Map operation is effectively giving you access to the internal memory buffer of the image. Vision normally controls the lifetime of that buffer and there are many operations (Dispose, Resize, Cast, etc) that could cause that buffer to have to be re-allocated (changing its pointer) or destroyed. Today, Map doesn't "protect" the image buffer in a way that safely prevents such operations from occurring - the user simply has to ensure their code around it is properly handling it and synchronized. The assumption when that interface was created was that user code should have to do a subsequent Unmap operation to let Vision know the buffer is no longer needed. Unfortunately, enough code is out there in the wild that omits the unmap operation (since it never was needed for the original implementation) that it would be difficult to enable this silently in a future version unless we had a newer Map function that was clearly marked that you needed to do an Unmap for proper operation (not leaking memory, allowing the image to be resized, etc).

 

You can see some of how this would look in practice by looking at how the EDVR (External Data Value Reference) works in the last few releases of Vision. You can think of it as Map Pixel Pointer, but in a way that lets you interact with the pixel data using the LabVIEW language instead of a Call Library Node and a DLL. Creating the EDVR is like Map, deleting it is like Unmap, and accessing it within the In-Place structure should (but seemingly doesn't, per the CAR I just filed) should invalidate any cached data for things like the Partical Analysis functions. Unlike today's Map/Unmap though, it does properly protect the image buffer so you can't write code that crashes with it. If you try to resize and image that has an active EDVR around it, it will not let you, and disposing the image itself will succeed, but the buffer holding the image data will stay around until the last EDVR reference is destroyed. This is the same as how the "proper" Map/Unmap would work.

 

edvr.png

 

Hope this helps explain things, and let me know if you have any more questions.


Eric

Message 15 of 18
(2,328 Views)

Yes, this explained it very well, thank you. And I can see the sense in it. The automatic reallocation is something you have to be extra careful with when using the pointers like I do. And I can tell you it did get me one or two times, or a hundred if we're honest. But I never actually expected it to be safe, that it's reasonable to say it's up to the application to guarantee it, one might say it's simply the price of the advantage of shared memory. That being said, I would wrap all my external functions to a safe scheme where I can simply wire in the IMAQ wires in an instant if the overhead was low enough.

 

Anyway, I think we might be drifting off topic here already. It's been educational, thanks again.

0 Kudos
Message 16 of 18
(2,316 Views)

@vekkuli wrote:

Yes, this explained it very well, thank you. And I can see the sense in it. The automatic reallocation is something you have to be extra careful with when using the pointers like I do. And I can tell you it did get me one or two times, or a hundred if we're honest. But I never actually expected it to be safe, that it's reasonable to say it's up to the application to guarantee it, one might say it's simply the price of the advantage of shared memory. That being said, I would wrap all my external functions to a safe scheme where I can simply wire in the IMAQ wires in an instant if the overhead was low enough.

 

Anyway, I think we might be drifting off topic here already. It's been educational, thanks again.


I'm not sure if it significantly helps, but if you wire the image wire to a CLN terminal which has the type "pointer-sized integer", it will be passed to your CLN as the same "Image*" type that Vision's C API uses. You can then make callbacks into the Vision library from C to things like imaqGetImageInfo() to extract all the information like the pointers and such. The one thing that isn't really exposed in the public API is the locking mechanisms for synchronization, so it doesn't make it any safer.

Message 17 of 18
(2,295 Views)

Huh, look at that, I didn't know that either. That's a neat trick, definitely the cleanest way to pass the image. The small overhead is there but other than that, it's fantastic. Thanks!

0 Kudos
Message 18 of 18
(2,287 Views)