Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

Skipped frames in image acquisition with 4 camera setup (2x 1430 cards), only recording around half the expected data

Solved!
Go to solution

Hi all,

 

I have a VI which sets up a continuous grab for four camera-link cameras at 100Hz (512x640).  I have the cameras running on an external 100Hz clock for synchronization (comes from NI DAQ box, trigger ports on the 1430 cards are not connected to anything).  The VI stuffs all the frames into a queue, and then I (slowly) have it written to disk after I acquire what I want.

 

The problem is, for a 4 minute capture, I only get around 14,000 items in the queue instead of 24,000.  Also, each image gets filled out with a buffer number, so I can see that it's not missing every other frame or something like that, sometimes it will skip 10 in a row, sometimes it will skip only a few... any ideas?

 

Here is an image of my collection setup (the write to disk part is not shown, but that empties the queue just fine) --

 

 

 

 

 

0 Kudos
Message 1 of 9
(4,999 Views)
Solution
Accepted by topic author mk@opc

Hi,

 

I can see a number of issues with the approach in your VI that I'll try to cover...

 

Your usage with the queues and images isn't going to work the way you wrote it because images are a reference data type and so putting them into queues doesn't copy the data values, only the references. Thus if you keep putting the same image reference into a queue, they all point to the same image data (that may be getting overridden).

 

A better approach is to have two queues of images, one that represents "free" buffers and then one that represents "full" images (your current consumer queue). You would then have your acquisition loop pull a "free" image, fill it with data via a Get Buffer call, and then queue it to your consumer. Your consumer would pull from that queue, do its thing, and then queue the image back to the "free" queue for the producer to use again.

 

Additionally, your code is not currently using the lower level Get Buffer VI, so you are not taking advantage of the buffered I/O model IMAQ internally uses. The simple Grab Acquire VI will only return the newest image, but if you fall behind at all it doesn't use the FIFO at all. You want to call Get Buffer with an incremeenting buffer number so that you don't skip any buffers and are allowed to get behind up to the number of buffers in the configured buffer list.

 

Eric

Message 2 of 9
(4,989 Views)

Ah, I see, thank you ver much!

 

Instead of the reference to the image (which stays the same) I need to use a Get Buffer.  The Get Buffer will also help me with my frame skipping issue because it utilizes a FIFO to compensate for any hiccups in the process.

 

Are there any examples of this two-queue scheme you described?  Thanks again 🙂

 

 

0 Kudos
Message 3 of 9
(4,985 Views)

Blue,

 

I simply added ImageToArray before queueing and the output works now, I can't believe I didn't notice the frames weren't all the same before... you're a lifesaver!!

 

Also, do I replace the GrabAcquire with the GetBuffer?  Do I need to add anything (like configure list/configure buffer) to use GetBuffer?

 

Thanks again 🙂

 

0 Kudos
Message 4 of 9
(4,976 Views)

Hi,

 

Maybe a better suggestion is to see why you are using the queue in the first place. Effectively the internal buffer list already acts as a queue, and especially if you use the Ring examples, getting access to the images via Extract Buffer is an almost "free" operation (no copy needed). You can use the internal buffer list as your queue and not worry about managing your own queue. The whole point of the buffer list mechanism is so that you can do your processing in a consumer loop and let the producer "loop" be handled internally by the driver.

 

Your approach via ImageToArray (making the queue be a value type instead of a reference) certainly solves the issue, but you are now making extra copies of the data you don't need. Your effective data rate even with 4 cameras is still pretty low here, so I doubt your are CPU/memory bandwidth-bound, so it may not really matter performance-wise. However, your code has a lot of extra complexity that it doesn't need.

 

Eric

Message 5 of 9
(4,950 Views)

Eric,

 

I hear ya.  I'm planning to re-do the IMAQ acquire stuff, but am having trouble implementing it.  I did IMAQ Init -> Config List -> IMAQ Image Create/Config Buffer -> Start -> Get Buffer (with an increasing index) and nothing came out.  I guess I will try using Extract Buffer now, is there an example you can point me to?

 

The thing is, the current setup works not too shabby-ly.  At 50Hz not a single frame is skipped, at 75Hz around 5% are skipped, and at 100Hz 20% are skipped... so I am wondering what the root cause of that is... maybe triggering? -- http://digital.ni.com/public.nsf/allkb/6FFA526966E2D29386257AA80054730A -- what do you think?

 

Thanks again!!

 

 

0 Kudos
Message 6 of 9
(4,945 Views)

Look at the "LL Ring" example. This is the best starting point. Set your number of buffers to very large (similar to how many you were prepared to queue previously) and then put your "consumer" code inside the main acquisition loop. This will not drop any frames unless you get so far behind that your buffer list is full.

 

If your camera is triggered directly, you can ignore any triggering stuff in IMAQ (and probably should). From the frame grabber's perspective, it is an untriggered acquisition.

Message 7 of 9
(4,940 Views)

Gotcha.  Working with LL Ring (dual port) now.  The problem is it takes super long to setup the buffers for anything over a few hundred frames.  I just ran a test with 6000 frames and it seems OK but the startup time is hard to deal with!

 

Thanks for all your help, Eric 🙂

0 Kudos
Message 8 of 9
(4,935 Views)

What version of NI-IMAQ are you using? I think around 4.7.3 there was a change that went in that made configure/unconfigure with large numbers of buffers significantly faster. There were some internal structures that had some exponential growth characterisics.

 

It still will be a bit slower than just allocating images in user mode for use in a queue, since the buffers are mapped to physical memory and scatter-gather lists for DMA are created, but hopefully is now fast enough.

0 Kudos
Message 9 of 9
(4,927 Views)