Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

high speed image acquisition

Solved!
Go to solution

I need to acquire images from a Basler ac2000-340 km camera with PCIe-1433 camera link interface. The rate is 300-340 fps but, importantly, I cannot afford to drop any frames or for the frame rate to fall because post-processing analysis requires an intect image sequence for accuracy. Data collection is need for only 2-3 minutes, giving about 50,000 images. The camera sensor is 2040x1088 pixels but usually I set the y-dimension to 200 or 300 pixels since that matches the shape of the object I'm imaging.

 

I've worked through the Brent Runnels high speed streaming ppt and decided I don't need to write to disk; I am content with collecting everything in memory by pushing the images into a queue ( I'm using a 64-bit Win 7 computer with 32 Gb memory) and then dequeueing and writing it all to disk as an AVI file afterwards. Using the following code almost works but the frame rate drops periodically and so it is unreliable; the slow down seems to occur because the IMAQ create vi is inside the loop.

 

queue8 v1.JPG

If I use the alternate code below, in which all the images are created in advance of collecting them, everything works fine, the frame rate is constant and no frames are dropped. However the first loop required to create the large set of IMAQ images (reserving memory for them?), takes several minutes to execute (particularly for 50,000 frames). (I'm only showing the critical part of the code, the other parts of the sequence simply dequeue the images and write the AVI file).

Queue8v2.JPG

 

Any suggestions on how to more efficiently do this?

 

thanks,

 

Mike Davis

0 Kudos
Message 1 of 16
(7,534 Views)

Hello Mike,

 

I hope you are good. I review the image of your code and I have a couple of suggestions. Creating the images references outside of the loop is considerably better in terms of performance. Have you considered using parallel loops to create the references? I mean if you want to create 50 000 image references, why not use two or more loops to create them in parallel? And them using the build array function to join the two or more arrays of references.

 

Are you using LabVIEW 64 bit or 32 bit? Remember that it does not matter if you have 32 Gb of Ram if you are using LabVIEW 32 bit.

Randy @Rscd27@
0 Kudos
Message 2 of 16
(7,499 Views)
Thanks for the suggestion: I will try it with parallel loops. Yes, I am using 64-bit LabView. Mike
0 Kudos
Message 3 of 16
(7,498 Views)

Hi Mike,

 

Here's my observations:

 

Your first example is using a ring of only 1 image inside of IMAQ and then copying data out into Vision images that you control purely in usermode. One issue I see with this design is that it is very easy to drop images if there is any CPU jitter because the hardware only has one buffer to write into and it will be blocked while the copy is occuring. You should probably be using 10+ images (or even more) at the high speeds you are going it. The second issue is that your buffer copy is consuming CPU and memory bandwidth of the system. Your overall data rates are not rediculous for a modern system, but it is still a bit wasteful to be copying data for no reason. You also are at the mercy of how deterministic the OS is at allocating large chunks of memory continuously.

 

Your second example is starting the way I'd have suggested, where you utilize the internal ring of IMAQ to store your images. This has the benefits of reducing an extra copy of the data. Also, since the ring images are page-locked by the system for DMA, they cannot be swapped out and you are virtually guaranteed that it will not fail after it has sucesfully configured the acquisition. Unfortunately it does have the downside of taking a longer amount of time because not only do the buffers need to allocated up front, but they need to be page-locked by the system and mapped into scatter-gather lists for the hardware to DMA into. I do believe that newer versions of the IMAQ driver may have improved this speed a bit, so you might want to try updating if you are using an older version.

 

My best suggestion would be to merge your two approaches. If you changed your top loop to use a ring that has maybe 500 images (a second or two worth of buffering) and then have it copy the images as you are currently doing, you'd have the benefit of being able to absorb much more CPU jitter in the acqusition loop than your current code with a ring of 1 image.

 

Eric

0 Kudos
Message 4 of 16
(7,495 Views)

@Rscd27 wrote:

 

I hope you are good. I review the image of your code and I have a couple of suggestions. Creating the images references outside of the loop is considerably better in terms of performance. Have you considered using parallel loops to create the references? I mean if you want to create 50 000 image references, why not use two or more loops to create them in parallel? And them using the build array function to join the two or more arrays of references.


I don't think this will help. The delay is not caused by the creation of the images themselves but rather the locking by the driver when the IMAQ session is configured. This operation is single-threaded.

 

Eric

Message 5 of 16
(7,493 Views)

Thanks for the feedback! Is always appreciate it.

Randy @Rscd27@
0 Kudos
Message 6 of 16
(7,474 Views)
Eric, thanks I will try that suggestion. Mike
0 Kudos
Message 7 of 16
(7,452 Views)

Eric,

 

Thanks for your help. Is the attached snapshot of code what you suggested?

Queue8 w ring.JPG

 

It seems to work but will need much more than 2 sec of buffering; based on my intial test in which I collected 10,00 frames, the frame rate started to drop after about 4,000 frames. (This is a new Dell precision 5810). Perhaps 10 sec of buffering is needed? Alternatively, the code I wrote could be inefficient.

 

Mike

0 Kudos
Message 8 of 16
(7,416 Views)

Eric, I tried the same code again with 10 sec of buffering (2500 buffers), to collect 10,000 frames, and the image acquisition actually got slower, with the slowdown beginning at an earlierframe number than with a 2 sec ring buffer.

 

To track the image acquisition speed, I embedded a time stamp as data into the AVI and then after the images were acquired and saved, I wrote a short program to read back the AVI, extract the data, and write it to an excel file; then I plotted the time between frame acquisition vs frame number in Excel. The slow down is easily detected by a change in the slope of that line.

 

Mike

0 Kudos
Message 9 of 16
(7,404 Views)
Hi Mike,

One thing that jumps out at me looking at your code is that I don't think your mechanism for tracking timestamps (and thus dropped frames) is accurate. You seem to be timing the acquisition loop itself. Since you now are using deeper buffering in the acquisition, it is specifically to allow jitter/pauses in that loop without dropping frames.

You should rely on the IMAQ driver itself to tell you if you are dropping frames. I believe there is a property node that will tell you if the hardware skips a frame because you fell too far behind. Additionally, since you are asking for consecutive frame numbers, if the buffer number you get back is not the same one you asked for, you know you fell behind. There may be an example that shows how to detect skipped frames like this as well.

Eric
0 Kudos
Message 10 of 16
(7,400 Views)