Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

Save images into array

Solved!
Go to solution

Hi all,

 

I know this has been asked before, and I've read many of the solutions, so I've added a bit of detail to clarify the issue...

 

LabVIEW 2013 SP1

Vision Assistant 2013 SP1

PCIe-1433 Camera Link Frame Grabber

Camera Link camera, 280 fps

 

I had an application that read images from the PCIe-1433, using 1 buffer.

I called the IMAQ Copy Acquired Buffer VI to copy the image from the buffer, and then I'd save that image onto disk.

That worked fine, but the disk access would slow it down after a few seconds.

 

So, with a little help from NI Support, I switched to use the (LL Ring example) multiple buffers.

Now I don't call the 'IMAQ Copy Acquired Buffer' VI, I call the 'IMAQ Extract Buffer' VI to get the images from the input buffer.

 

But, since I'm not copying the buffer to the 'working image space' (IMAQ Create), I now only have a reference to the image.

Is there another VI, or another way, to get the actual image so that I can store it?

 

At the moment we're capturing thousands of images for later processing, so I don't really want to create thousands of buffers at setup time to save all the images (as other examples had shown).

 

I hope that's clear.

Any thoughts?

 

Thanks,

Jeff

 

0 Kudos
Message 1 of 10
(6,976 Views)

I would recommend this webcast: High Speed Image Streaming from A to Z

http://www.ni.com/webcast/771/en/

It's a little long, but provides good resources on how to configure your hardware to maximize performances.

Using a ring is the best solution. IMAQ Extract Buffer locks the buffer while you write it to disk, avoiding a copy and saving a bit of time.

In which format would you like to save the images?

 

0 Kudos
Message 2 of 10
(6,973 Views)

It really depends on your application.

 

The big problem with streaming to disk is that it is usually slower than the acquisition.  If you want to store a large number of images, you need to be able to store them as fast as you acquire them.

 

One way, as you mentioned, is to create all the buffers you will need in advance and fill them during the acquisition.

 

Another way is writing directly to disk.  I will be impressed if you can write 280 fps to the disk and keep up.  Your buffer will need to be big enough that the acquisition is done before the buffer overflows.

 

One trick I have used is compressing the images to JPEG strings, then storing the strings in memory.  Computers are usually fast enough to keep up since you aren't writing to disk, and the strings take less space than the full image.  You can set the quality fairly high if you can't afford to lose details.  Afterwards, you can write the strings to disk at  a leisurely pace, or convert them back to images (oops, hard to do that because NI doesn't think it is an important function) and analyze them.

 

Bruce

Bruce Ammons
Ammons Engineering
0 Kudos
Message 3 of 10
(6,966 Views)

Hi ChristopheC,

 

Thank you for your suggestion, I will view the webcast.

 

You ask about which format I need.

Well, after I save the images, I go back in a leisurely manner, read them from the file, and use the NI vision tools like IMAQ Match Pattern 4, IMAQ ROIProfile, IMAQ Simple Edge, to collect data from the images.

Each of these VI tools use 'image' as in input, so I don't think I have a choice as to format.  Feel free to correct me if I'm wrong.

 

 

Thanks for your input,

Jeff

 

 

0 Kudos
Message 4 of 10
(6,948 Views)

Hi Jeff.

 

> You ask about which format I need.

 

I meant do you want to save the images individually, as an AVI file, a TDMS file?

 

You basically have different options to try to achieve real time streaming to disk. The webcast I sent, along with this app note explain how to configure the disk and using RAID to obtain the best performances:

http://www.ni.com/example/2909/en/

That application note also has an example you can look at.

 

Other solutions include using the AVI VIs to write the data. By using AVI, you are compromising processor time to compress the data vs a smaller file to write.

Some codecs are lossless. Some not. The use of compression depends on your application. The result will be one or more AVI files, that you can read offline using the Read AVI VI.

 

The third solution is to save the images as a TDMS file.

http://www.ni.com/white-paper/3727/en/

To do that, use the IMAQ ImageToEDVR VI to access the 1D array of image data of your extracted buffer. The EDVR functions allow to access the data as a LabVIEW array without making a copy, that you can then pass to TDMS Write.

You'll end up with a TDMS file that you can read offline using the TDMS Read VI in LabVIEW.

 

You going to have to experiment to see which method allow to maintain the throughput you need, and if several qualify, choose the format that you like best.

 

Hope this helps and is not too confusing.

 

Christophe

0 Kudos
Message 5 of 10
(6,941 Views)

Hi Chirstophe,

 

Early in this project, I tried AVI files.

Unfortunately they have a size limit of 2 GB, and I'm saving around 5-6 GB.

At the moment I'm creating a cluster with a time stamp, the image, and another flag, then writing the structure to a binary file.

 

I hadn't heard of TMDS files, I'll check into that.

 

Thanks,

Jeff

 

0 Kudos
Message 6 of 10
(6,937 Views)

Yes, when we updated the AVI functions, we used a different underlying API without realizing right away that we introduced the 2GB limit.

Try using the old API that we still ship to maintain compatibility, but is not exposed in the palette. You can find it in the llbs: AVI1.llb and AVI2.llb in the folder C:\Program Files (x86)\National Instruments\LabVIEW\vi.lib\vision

The old API is based on a different technology and should allow you to read and write > 2GB files. It is not supported on RT targets, but it does not seem you're using any. This might be a workaround if you still want to use the AVI file format.

 

0 Kudos
Message 7 of 10
(6,932 Views)

Hi Chritophe,

 

Thank you for the reply and historical insight.

I'm happy with the binary file that I'm using (assuming I can make it work for speed).

 

But, I think we've gotten a little off topic.

What I'm trying to do now is just save the image.

When I switched from a single buffer approach to the multi-buffer approach the code I use to bundle the image and other parameters into a cluster, no longer saves the images.

I'm still trying to work out how to save each of the images as they go by...

 

Thanks for the suggestions,

Jeff

 

 

0 Kudos
Message 8 of 10
(6,930 Views)
Solution
Accepted by DMJeff

Hi all,

 

I talked this over with Earl at NI Tech Support, he was very helpful.

 

Apparently, when I capture an image buffer, I get a reference to that buffer location (I knew that).

When I was passed the image to the 'Write Binary File' VI, that tool was dereferencing the image (copying the image pixels to the binary file).  (apparently not documented where I could find it)

However, when I replaced the 'Write Binary File' VI with the 'Insert to Array' VI, LabVIEW does not dereference the pointer, and stores the reference.

And, there seems to be no 'Derefrence this pointer' tool.

 

So, what we came up with...

 

After getting capturing the image from the buffer, I pass the 'Image' (pointer) to the 'Copy Image to Array' VI.

That gives me a 2-D array containing the actual pixels from the image, and NOT a reference.

Then I save that image data in my array.

After I capture all my images, the loop is done, I loop through the Array, read back the 2-D array, and pass it to 'Copy Arry to Image' VI to get the image back.

I then write the image to the binary file for safe keeping.

 

By doing this, the other utilitiy applications that already exist to read in the binary file should be compatible with the file that is created.

 

Thanks for all the ideas and thoughts.

Jeff

 

0 Kudos
Message 9 of 10
(6,919 Views)
If you capture all the images into RAM before you write them, it is far more efficient to just use a sequence acquisition which uses IMAQ's internal buffer list of images. This requires zero CPU usage while running and can't fall behind (unless your PCIe link to memory can't keep up). Then you can convert to an array and write he images to disk in the same way after it completes (although there are more efficient ways to do this as well).
0 Kudos
Message 10 of 10
(6,914 Views)