Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

How to save 16 bit images from high frame rate camera in real-time

Hello my name is David and I am trying to save 16 bit images generated from a Hamamatsu camera that has a frame rate of 30 to 60 fps depending on binning. For 30 fps my image size is 1000x1000 and for 60 fps my image size is 512x512.  I want to stream images for anywhere from 10 seconds (300 images) to 1 minute (1800 images) and save each image. I don't want to alter the image by casting it to 8bit or to rgb to take advantage of the avi save option. I am using a Dell pws380 with P4 3.0 ghz cpu and 2gb memory. I currently have implemented a ring buffer style system where at the start of my app I generate an imaq image array of 700 (30fps) to 1500 (60fps) images depending on binning. I then allocate an estimated number of frames to use from the array for a given amount of time. 
During streaming time I have two while loops running simultaneously. One loop that acquires images and the other loop ( which I start 1 second after streaming begins) to save images and and free buffer elements. This works fine for save times of less than 15 seconds at 30 fps. For my computer I notice that it takes approx. 100 ms to 300 ms to save an image. Is there anyway to speed up the saving to allow for faster saves and also any way to improve on my ring buffer acquisition style? Any help would be most appreciated.

David Charlot


0 Kudos
Message 1 of 13
(7,038 Views)

Hi,

 

Regarding streaming images to disk, we have found that converting the image to an array and using the standard file I/O vis is faster than the vision file vis. Use the Open/Create/Replace to open the file at the start of the recording and then use Write  to write each image array and Close at the end of the recording.

Hope this helps a bit.

 

Mike

 

0 Kudos
Message 2 of 13
(7,011 Views)
Hello David.

The high data rate (16bit x 1000 x 1000 x 30 fps  is  ~57MB/sec) requires a very fast hard disk.
My hard disk typically achieves write speeds of up to 53MB/sec. You can check the performance of your disk e.g. with Performance Monitor.
If the transfer rate isn't satisfying you might need a disk array.

Regards, Guenter
0 Kudos
Message 3 of 13
(6,998 Views)
Thanks for your reply. I did something to that effect. The dll I use to extract frames from my camera outputs 2d arrays. I was converting the 2d array to an Imaq image then saving the Imaq data as a tiff. That was adding a lot of time to the loop. I instead now have a 2d array queue setup that works great. In the image acquisition while loop I add each new frame into the queue. In the dequeue loop I write the 2d array into a datalog file. The camera frame rate is not compromised in any way ( I am able to still have the 30fps). On average I am finding that each image takes approx 350 ms to save. So for every 30ms image acquisition time, I need 350 ms to save. That means I need approx 20 second save time for every 10 seconds acquisition time. Thanks for your help. My images are 1k by 1k. The average save time would be faster if the images weren't so large.



David Charlot
0 Kudos
Message 4 of 13
(6,988 Views)
Hey David (and Mike who posted earlier),
 
To verify what you all were seeing, I wanted to just set up a quick test to see how long it would take to use the IMAQ Write Tiff VI and I set up a program to create a 1000x1000 16 bit image and then save it to file using the same VI that you showed in your screenshot. I was getting times around 20-45 ms. This is about 1/10th the time that you are claiming it is taking you VI to save an image to file. I don't know what you are doing differently, but I don't think it is the Vision function that is causing your program to save to an image file so slowly.
 
When Mike says he uses the normal file I/O VI's included in LabVIEW, this makes sense in his case because he is not opening and closing a new file for every image file he wants to save. Just like if you would use the AVI functions, you are keeping the File open and then writing the image data to just one file and not multiple files. It is expected that the File I/O would take longer if you are creating 1000 files or just one file. I am sure that if you opened the 1000 files before the loop to acquire at 30 fps would start and then just change the reference to those files to write the data to, then it would be a lot faster.
 
Now David, I see that you are not using the NI-IMAQ VI's to acquire your image, and you said that you are just getting them from your camera's DLL. Therefore, you would save some time by just writing the image data to file without converting it to an IMAQ image. But if you were using an NI Framegrabber, and acquiring the images using the NI-IMAQ VI's, then you would want to just use one loop and set up a Ring type of acquisition. This would allow you to get the images off of the ring as fast as you could write them to file. I am sure that this would be a lot faster than 350 ms total time to acquire and save the images to file, especially if you have a raid array like was mentioned in the other previous post.
 
I hope this helps clear up some confusion that might be going on in this thread. You can also set up a simple test by just creating an image by using nested for loops and an IMAQ Array to Image, then placing a Tick count in a sequence structure before and after the IMAQ Write to Tiff File.VI. This should not be taking 350 ms to save to disk if you are doing it correctly.
 
Regards,
DJ L.
0 Kudos
Message 5 of 13
(6,966 Views)

Thanks you for your reply. I did a similar test to see how long it takes to save an image and my computer may just be slower compared to yours. For my particular application however I need to acquire 10 second image sequences at strict intervals. I made a test vi where i just make a 16bit 2d array that is 1k by 1k. I convert this array into an Imaq image. I then save this single image 300 times in a for loop. It takes between 16 and 17 seconds to save all 300 images. So if i want to preserve the frame rate of the camera, I cannot acquire and save at the same time in the same while or for loop. This requires a queue of some sort. 

 

 

David Charlot 

0 Kudos
Message 6 of 13
(6,962 Views)
Hey David,
 
We are using different computers, but I doubt mine is any better or faster than yours, as you have much more memory than I do and a faster processor. I also do not have a disk controller to save data faster, so your computer should be able to go faster than mine.  On the other hand, I am glad to hear the time to save your images is not in the magnitude of 300-350 ms anymore. After doing some calculations on the times that you posted, it seems that the time it takes to save is now down to around 55 ms instead of 300 ms.
 
16-17 seconds let's say is 16.5 seconds on average
16.5 seconds times 1000 ms (for one second) = 16500
16500 ms total divided by 300 images = 55 ms per image
 
Also, I understand that because you are using a 3rd party dll that gives you a 2-D array of data back instead of an IMAQ Image. So because it does take some time to convert the 2-D array into an IMAQ Image, then you might just want to save the 2-D data without converting it into an image. Just something to think about.
 
I am not sure how the 3rd party DLL that you are using is acquiring the images into memory, but like I mentioned above, if you were using the NI-IMAQ driver with an NI framegrabber, then you would be able to acquire your images into memory at the specified time intervals without having to worry about the time it takes to do anything else to the images (like save to file in this case). This is because the images would come into system memory at the rate you want (and the interval you want), and this would kind of happen in the background for you, not dependent on any software timing, like in a loop in your program. The only thing that would be software timed would be how long the images get processed (or saved to file). The acquisition would all be handled in a separate thread almost, which is handled by the NI-IMAQ driver software. In your case, how you are queueing up images, you are depending on your system to time the framerate it seems, not based on the hardware or driver, but based on how fast your system can perform an action. So also in your case, you would want to use a queue, because your image acquisition is software timed it seems, but anyone else that might read this discussion forum thread would not want to use queues because the IMAQ Image data type is like a pointer to the memory location where the images come into. Thus, in a Ring the one loop is only needed because the driver is acquiring the images into memory in the background for you, and then you just come along and extract the images off of the Ring (like a queue or a stack) and then process or save the image to file while the driver is still acquiring images into the next memory location. This is why I recommended that you consider using the NI-IMAQ driver if possible. But if you want to use the 3rd party DLL, or if you have to because you have a 3rd party framegrabber, then it all depends on how that DLL works, which will determine how you have to program, which could mean that you do need to use a queue. For most users using NI IMAQ functions, the use of Queues is not necessary.

I hope this helps and I hope this clears things up as to what I was talking about. Please let me know if you have any further questions or concerns. Thanks, good luck with your applications, and have a great day.
 
Regards,
DJ L.
0 Kudos
Message 7 of 13
(6,951 Views)
Hello all who posted or who will read this post. I want to update you all with my fast frame rate streaming to disk issue. So it turns out there was something wrong with my installation of windows and the harddrive on which it was installed. I got another harddrive and have a fresh install of windows and labview. I am now able to stream to disk in real time using the save imaq to tiff just fine. The key to speed is to know how many images you need to save in advance so you will already have the filenames already generated. When i was generating the filename in the same loop as the acquisition loop it took up some time. My hardware setup is xeon 3.0 cpu, 4 gb memory, 300 gb sata II harddrive for windows install and I stream my data to 2 500gb harddrives setup as raid 0.


David Charlot.
0 Kudos
Message 8 of 13
(6,883 Views)
I also wanted to add one more thing to this thread that I think is an important and useful document. There is a great DevZone document called Streaming Images to Disk with NI Vision that is a great resource for how to set up a high throughput streaming system, and it also serves as a guideline for developing a system to meet your requirements. This document talks about using off the shelf hardware to create a cost effective solution for streaming lots of image data to file while you are acquiring. As you can see in previous posts, David followed the Raid 0 controller setup with multiple hard drives for his solution.
 
Regards,
DJ L.
0 Kudos
Message 9 of 13
(6,870 Views)

Dear All,

 

I see this string to be very useful to me, I too wish to have high speed acquisition and saving, without any loss of frames. As a beginner  I have started with the VI programs (LL_ring_write_images.vi) given at Streaming Images to Disk with NI Vision. For the 1000 - 2000 fps (100 x 100 pixel and 1 milli second exposure) I am able to save the images without losing of frames. However, when I increase the frame rate to 5000 and above (100 x 100 pixel and 0.1 msec exposure) I start losing the frames. What can I do for it?

Finally, the LL_ring_write_images.vi saves all the acquired images as one file with a bin extension. Can I directly save it  as 16 bit images?

 

 

Thank you very much

 

Kind regards

Shiju

0 Kudos
Message 10 of 13
(5,903 Views)