07-24-2017 01:32 PM - edited 07-24-2017 01:34 PM
Hello all,
I'm working on a high speed image processing project where the camera can reach up to 80KHz rate. The setup has trigger at 12.5usec to capture the frame. I need to capture every frame and process 1024 frames at a time (one process requires to have 1024 image data - each raw data has 1x2048 data). I capture -> count/build into 1024 image data -> process data and display.
My problem is when I run this, the whole processing becomes really slow (it takes about 8 secs to collect 1024 images and process them). I benchmark each state and I believe the bottleneck is at count/building an array to store 1024 image data in buffer (It takes 100 msec to process 1024 image data and 12.8 msec to collect 1024 images). I've been looking to optimize the code but running out of idea.
When I removed the part where I build an array, input/output image buffer number matches. When I leave the part where I build an array and count to 1024 with queue, input/output buffer starts to mismatch.
I wonder if anyone had similar project and would share how to resolve this issue? I think it's the way I programmed it, there must be a better way.
I'm using a windows PC with LV 2016.
Thank you in advance.
Best
Solved! Go to Solution.
07-24-2017 01:51 PM
Converting each image to an array is probably using a lot of time, and copying the large 2D array would take a lot of time.
I would allocate a large array of image buffers (maybe 4096) and loop through them. Once you have 1024, send a 1D array of image buffers to your analysis routine. Your image acquisition should be able to keep up this way. The only problem with this is that the buffers will be overwritten if your analysis is slower than the acquisition. You would need to do some buffer management to prevent overwriting buffers that haven't been analyzed yet.
Okay, just realized you are acquiring 1 line images. That makes it really slow. I would set it up to acquire 1024 line images, then transfer each image buffer for analysis. You would still want to create a large array of image buffers, but it will take a while before you start overwriting images.
Bruce
07-24-2017 02:33 PM
When working with a line scan camera you usually would want to build image of 256x2048 or similar in the acquisition loop and copy the whole image into processing loop.
You need to pre-allocate that image size and copy line by line to fill up the larger buffer in your acquisition loop.
To prevent lines disappear while you copy the larger image you will want in the acquisition loop to allocate at least 15 - 20 buffers.
07-24-2017 04:13 PM
There is a setting somewhere so you can set the number of lines accumulated in a single image. The acquisition will return the lines as a single image. For example, you can tell it to give you 1024 line images, and it will give you a 1024 line image each time the internal buffer fills. This eliminates a lot of the tedium that would be involved if you acquire one line at a time and try to do the image management yourself.
Bruce
07-25-2017 02:48 AM - edited 07-25-2017 02:54 AM
Thank you Amit and Bruce.
I can't find an option to set the number of lines and get chuck of images. I used FOR loop to collect all 1024 images and send the whole 1024x2048 data. This made a significant improvement (I'm getting 2.5 seconds per process) but still too slow. I need to get 10-15 fps of processed images. Can you point me where to find the option/function to get chuck of images instead of individual image?
Also, how can I stop/clear the buffer? I can't seem to stop the loop until buffer is cleared.
Much appreciated.
Thanks.
07-25-2017 09:48 AM
I am pretty sure you set up the number of lines per image using MAX under acquisition attributes. I suspect you can set the same parameter using property nodes if the number needs to change.
Bruce
07-25-2017 01:59 PM
Since this is an IMAQdx device, it is not using a framegrabber. The number of lines is thus a camera attribute is is usually just the acquisition height (for most linescan cameras). If it is an area-scan camera that you are only using a single line from, then the camera would have to support a special custom mode to concatenate lines from multiple exposures.
Beyond combining lines, some general suggestions to make your acquisition faster:
-Don't use the labview event loop. Use IMAQdx blocking calls instead.
-Use a ring acquisition instead so image data doesn't need to be copied
-Use the EDVR VIs on the Vision palette to get access to the line data as an array without copying
There is a good example shipped you can reference called "Low-level Ring Parallel Workers.vi". This demonstrates how to queue buffers to a separate worker thread in an efficient manner (remove all but one worker loop). There is another Vision example VI shipped called "Image to EDVR.vi" that shows how to use the EVDR within your worker loop.
07-25-2017 02:10 PM
If you can set up the number of lines in MAX then that is the best way.
But I have also notice you are using Image 2 Array VI to copy the image.
That isn't a good way.
What you want to do is to use allocate a large image as the target image.
You do that by creating image and then us using IMAQ SetImageSize.vi to 256x2048 image size.
Then use IMAQ SetRawCol.vi to copy every line into the larger image.
Image to array isn't very efficient VI.
07-26-2017 01:12 AM
Thank you Bruce, Amit, Bluecheese.
I resolved my issue by setting the height to 1024 and replacing ImageToArray with EDVR, now I'm getting 15 FPS.
Thank you all. Wish I could choose all as a solution.
Best.
07-26-2017 04:16 PM
Can you post your final code? A picture is a thousand words and all...