Jump to content

Vision Refs


Recommended Posts

Hi gang,

Simple question, can I treat a Vision Images ref just like any other U32 ref with all the rules applicable like forking wires etc? It seems to me that there is some kind of special stuff going on with Vision Image refs.

Another related question, in my particular use case I have a piece of code generating a user event with an image as the data at some arbitrary fast rate. The act of Generating the user event creates the a copy, right? Some other code wants to process some of these frames (at a slower rate) and then I use IMAQ Copy to make a local copy, is this IMAQ Copy necessary or could I just hold onto the "Image" reference coming in from the user event? In the code below Images is just a local buffer I plan on using.

Capture.JPG

 

The reason I ask is I am getting some weird behaviour whereby destroying my Images refs as shown in Capture3.jpg kills my acquisition code as well. (I presume because I am forcing all images to be destroyed, but I am surprised this is happening)

Capture2.JPG

Capture3.JPG

Edited by Neil Pate
Link to comment
2 minutes ago, drjdpowell said:

Cast it to a U64 instead of an I32; then the numbers are different.

Bingo! Thanks James.

So Image refs are just plain old normal U64 size refs? I sometimes wish there was a way to see refs as native "pointers" in a probe rather than the special type (i.e. the image). I suppose I could create a custom probe and just display the U64...

Link to comment
1 hour ago, Neil Pate said:

Another related question, in my particular use case I have a piece of code generating a user event with an image as the data at some arbitrary fast rate. The act of Generating the user event creates the a copy, right

I always find images annoying because the are by-ref.  You send a copy of the reference to the image, not a copy of the image.  

Link to comment
2 minutes ago, drjdpowell said:

I always find images annoying because the are by-ref.  You send a copy of the reference to the image, not a copy of the image.  

But they are kinda ByVal as you wire into an indicator to actually display the image. You cannot just make that association once and then assume it will automatically get updated.

Link to comment

Well, to dequeue from a Queue, you have to provide the Queue reference every time.  You can't call dequeue once and have it automatically keep happening.  The confusing thing is that it is we write the Image Ref to a Control Terminal, rather than a VI.  That's what fools us into thinking of passing images by-value.

Link to comment

Images are bizarre. My experience using them lately is that I basically don't trust anything that they do without testing. 

In the first case, I don't think you need to copy the image into a local reference unless you want to do several processing steps on it (where the source reference could be updated between steps). If you just want to display the image I think the image display makes a copy of the image data pointed to by the refnum. Usually. I also could swear I've seen it automatically update sometimes, but in the code I was working on last week, it didn't. See below.

That having been said, unless there is a performance concern I'd just make the copy. I've personally found that its easier and less painful to re-create dataflow manually through several data copies than it is to deal with the references -- copying a sequential chunk of memory is not expensive.

Its worth mentioning my biggest problem with images -- the references are named in a global namespace. I had several months of issues related to flattening and unflattening images at runtime and causing camera A to be mixed up with camera B, or the display suddenly getting populated with week-old data because I read from a file where the flattened images had the same name. Anyway this experience taught me to be super aggressive with copies, and all my images use GUIDs for names. Copy, copy, copy. Where performance is less of a concern I started using ImageToArray and passing around the 2D pixel array dataflow-style. Because seriously screw globally named references. :throwpc:

Quote

The reason I ask is I am getting some weird behaviour whereby destroying my Images refs as shown in Capture3.jpg kills my acquisition code as well. (I presume because I am forcing all images to be destroyed, but I am surprised this is happening) 

This seems more straightforward. If you dispose of all images, acquisition should fail since there is no memory space to put new images into. Am I misunderstanding?

Edited by smithd
Link to comment

Yes.  With snapshot off, the image redraws from the buffer whenever it refreshes.  Writing to a terminal triggers a refresh**, but you can also do it by the "Refresh Image" Method.

** Note: LabVIEW controls are running in the UI thread and are asynchronous to their terminal, so writing an Image ref to a terminal only schedules an update for possibly several milliseconds in the future, by which time the image may have been overwritten.  I think this may also be a big source of confusion, as with by-value data the delay is never a problem, but with by reference data it is.

Edited by drjdpowell
Link to comment
  • 2 months later...

The IMAQ datatype is a special thing. It is in fact a refnum that "refers" to a memory location that holds the entire image information, and that is not just the pixeldata itself but also additional information such as ROI, scaling, calibration, etc. Just as passing a file refnum to a file function does not pass a copy of the file to the function to operate on, so does passing an IMAQ refnum not create a copy of the data. It at most creates a copy of the refnum (and increments an internal refcount in the actual image data structure). The IMAQ control does the same. It increases the refcount so the image stays in memory, and decreases the refcount for the previous image when another IMAQ refnum is written into the control.

And there is a good reason that NI decided to use a refnum type for images. If it would operate on them by value just as with other wire data, you would be pretty hard pressured to process even moderately sized images on a normal computer. And it would get terribly slow too, if at every wire branching, LabIEW would start to create a new by value image and copy all the potentially 100MB and more data from the original image into that copy.

And if you wire a true constant to the destroy all? input on the IMAQ Destroy function this simply tells IMAQ to actually destroy any and every image that is currently allocated by IMAQ. And if you do that you can in fact save yourself the trouble of calling this function in a loop multiple times to destroy each IMAQ refnum individually. But yes, it will basically destroy any and every IMAQ refnum currently in memory, so there is no surprise that your IMAQ control suddenly turns blank as the image it displays is yanked out of memory under its feet.

And why would they have added this option to the IMAQ Destroy? Well, it's pretty usual to create temporary images during image analysis functions and give them a specific name. If they don't exist they will be created and once they are in memory they will be looked up by their name and reused. So you don't typically want to destroy them after every image analysis round but just let them hang around in memory to be reused in the next execution of the analysis routine. But then to properly destroy them at the end of the application, you would have to store them in some queue or buffer somewhere to refer to them just before exiting and pass that refnum explicitly to the IMAQ Destroy function. Instead you can simply call IMAQ Destroy with that boolean set to true, to destroy any IMAQ refnums that were left lingering around.

Edited by rolfk
Link to comment
On 1/20/2017 at 1:21 AM, Neil Pate said:

Bingo! Thanks James.

So Image refs are just plain old normal U64 size refs? I sometimes wish there was a way to see refs as native "pointers" in a probe rather than the special type (i.e. the image). I suppose I could create a custom probe and just display the U64...

 

On 1/20/2017 at 0:20 AM, Neil Pate said:

More strangeness (probably just me not getting something).

Why are all four Image references the same? 

Capture4.JPG

Your reference id: 0x496d6167 is hex ascii for "Imag". That is, it's the first four bytes of your image name. Images are string references a bit like a named queue.

It's too bad Image Refs came before DVRs. It would have been much simpler to understand if you knew the DVR syntax.

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.