LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Saving all images as last collected image with Queue

Solved!
Go to solution

Hello,

I am currently running a camera that collects images at around 500 fps and am using a Queue to temporarily store them so they can be saved after all images are collected. If they are saving while capturing it significantly reduces the frame rate. My problem is that while running it appears to be saving all the images in the queue sequentially but when the saving code saves the images they are all saved with last image captured. My understanding of how the queue works may be incorrect, but from how I think it works this code should work. Any help would be greatly appreciated. 

Thanks

0 Kudos
Message 1 of 19
(3,368 Views)
Solution
Accepted by topic author danderson1

Your problem is that you aren't enqueuing an image, you are enqueuing the IMAQ reference.  The reference points to a single memory location which gets replaced by new image data.  You basically have an array of references that all point to a single memory location, and at the end, that memory location contains the image data for the last image.

 

You need to create a new IMAQ reference for each image you are enqueuing.

Message 2 of 19
(3,365 Views)

Looking at your code, I see that you have two loops that execute sequentially. This will cause your code to run for quite a long time. You should use a producer/consumer design pattern to capture and save data in parallel.

Acquire your images in the producer loop at your desired framerate, save your images in a consumer loop at a slower rate. Use a queue to send data from producer to consumer.

 

See this link: http://www.ni.com/white-paper/3023/en/

Message 3 of 19
(3,364 Views)

Thanks for the help. How would I go about doing that? I tried giving the IMAQ grab a specific number of memory locations, but doesn't seem to work. Would I need to use something like configure ring acquisition? 

0 Kudos
Message 4 of 19
(3,350 Views)

Thanks for the help, I've read a little bit about them but was unsure if it would be able to guarantee a desired framerate?

0 Kudos
Message 5 of 19
(3,346 Views)

You definitely want a producer/consumer pattern.  But instead of queuing up IMAQ references, convert the image to data in the same loop you are acquiring.  Then queue that image data up. In the consumer loop, which should run in parallel to the producer loop, it will dequeue the data and write it out to the file.

 

How long are you running the image acquisition?  If the file writing is occurring slower than the image acquisition, eventually you'll fill up memory with the image data waiting to be written out.  The longer your run, the more likely it will be to fill up memory.

Message 6 of 19
(3,320 Views)

@RavensFan wrote:

You definitely want a producer/consumer pattern. 


Not necessarily. If these actions (acquire and store) are sequential, you could (should?) program it sequential.

 

No need for a queue either, and array would work Smiley Very Happy.

0 Kudos
Message 7 of 19
(3,295 Views)

Except he is describing a problem where the sequential process is taking longer than he wants.  In which case it should be broken up into two.

 

However, if the 2nd part (saving) takes too much longer than the 1st (acquiring), the backlog of work in the queue or array will eventually build up, and if it goes on too long, he'll run out of memory.

0 Kudos
Message 8 of 19
(3,287 Views)

@RavensFan wrote:

Except he is describing a problem where the sequential process is taking longer than he wants.  In which case it should be broken up into two.


I don't think he does. He mentions the storage need to take place after acquisition:

 


@danderson1 wrote:

Hello,

using a Queue to temporarily store them so they can be saved after all images are collected. If they are saving while capturing it significantly reduces the frame rate. 

and that images get lost:

 


@danderson1 wrote:

while running it appears to be saving all the images in the queue sequentially but when the saving code saves the images they are all saved with last image captured.


Nothing about speed or thinks taking too long? Maybe I missed that (dyslectic, not using LabVIEW just for fun).

 


@RavensFan wrote:

However, if the 2nd part (saving) takes too much longer than the 1st (acquiring), the backlog of work in the queue or array will eventually build up, and if it goes on too long, he'll run out of memory.


Of course he'll run out of memory. But as I get his post, storing during the acquisition is not an option. So, parallel execution is not an option, so sequential execution is in place, so might as well use a sequential program, as it is the simplest solution.

0 Kudos
Message 9 of 19
(3,282 Views)

His original message was about why the previous images were lost and he was only getting the last image.  I answered that in message 2 about how what he was queuing up was a reference to a specific memory location that is always overwritten when a new image comes in.  The value that is on the purple wire getting queued up isn't a reference to a specific image, just a memory location that holds image data that will change whenever new images are acquired. The OP had actually marked message #2 as the solution, but later rescinded that.  I'm not sure why, because it is the solution to the question he had posted.

 

But in message 1, he described his original problem that his reason for trying save all the images after collecting was not because that is what he necessarily wanted to do, but he did that thinking it would fix his problem of a slow down in frame rate.  So his real problem he is trying to solve is a slow frame rate.  Saving each image after acquiring it in a sequential manner is too slow.  (Now how slow that is or how fast he needs it to be wasn't mentioned.)

 

Technically, a producer/consumer architecture is a sequential operation in that the consumer can't operate on a piece of data in the queue until after the producer has put it there.  The parallel part is that it can do it at its own pace while allowing the producer to move on and produce additional data.  Thus the two loops are operating in parallel.

 

Parallel execution IS an option in his case.  It allows the consumer to do some work, albeit saving image data to a file at a much slower rate than the producer is acquiring the data.  The architecture should allow the code to run a little bit longer before running out of memory than storing up all the data before writing to the file.  The key thing the OP needs to do is get the actual image data provided by purple IMAQ reference stored in the queue and not just the IMAQ reference.  This needs to happen whether he does it fully sequential like his original VI shows, or he improves upon it and turns the 2nd loop in the sequence into a loop that can run parallel to the 1st loop.

Message 10 of 19
(3,275 Views)