I am using a PCIe-8244 four cameras. I am trying to write a code that saves 10 minute video files from all four cameras, independently triggered. This sounds pretty easy, but is actually quite challenging. My cameras only acquire at 30fps, saving a video at this frequency excedes the 2GB limit on IMAQdx. As such I am lowering the video collection to 10 fps, however the cameras still acquire and are displayed at 30fps.
I was hoping adding more RAM (16GB) and using the PCIe-8244 would be enough to make this function, but the collection loops run slow regardless of what type of loop I am using. I have tried all four in timed loops, with automatic selection of processor and selecting each processor core individually (i5). I have tried a combination of timed loops and of "wait until next ms" while loop strategy, and have tried 4 while loops. None of these options are close to accurate for saving frames at 10 fps.
Is this an impossible task? If it is not please let me know what I can change in my code. I tried to keep it as neat as possible!
Have you tried logging to an AVI file with just one camera for benchmarking purposes? I am curious what speeds you can reach using a single camera to write an AVI file. If you are unable to achieve desired speeds with a single camera, then the problem goes beyond using four camera simultaneously. I would recommend running a simple program to test AVI logging with a single camera and see what the achievable performance is. I have attached a fairly simple IMAQdx VI that should help with this.
In regards to your questions about memory usage, I would like to point out that the 2GB limit is not imposed by IMAQdx. This is a limitation of how the Windows operating system addresses memory to 32-bit application. LabVIEW 32-bit is generally only able to access 2GB of system memory when running on either 32-bit or 64-bit versions of Windows. To avoid this limitation, you may use the 64-bit version of LabVEIW. However please note that not every NI software product has a 64-bit version, so some other toolkits or modules you may be using may not be compatible with LabVIEW 64-bit. I encourage you to read this Knowledge Base article for more information:
If I reduce the code attached in the original post to 1 camera the video saves on time at 10 fps without a problem.
The example attached is similar, however it does not directly work for this hardware. The camera is a webcam and it can only run at 30 fps. Changing the avi write function to 10 fps does not change the loop iteration, thus all frames at 30 fps are saved, however playback is a 10 fps making it a slow motion video. I have found that in this situation the best method to change the aviwrite function loop iteration is to return it to its own loop. (I think I found this in a seperate example)
I don’t understand what you mean by saying the example “does not work directly for this hardware.” The example I provided will work with any USB camera.
The “Frames Per Second for AVI Playback” is independent from the acquisition rate of your camera. If you want playback to occur in normal time, then you should set this property to match the acquisition rate of your camera. That would be 30 FPS for your webcam from what you’ve said.
And looking at your program, it seems there is room for optimization. For example the AVI Creation VI is called every loop iteration for each camera. That means this VI enumerates the AVI codecs and overwrites the previous AVI file every loop iteration. This is unnecessary and will only slow down your program by consuming excessive computer resources. That is why I recommended you start with a more straightforward and efficient example, then expand that to accommodate four cameras.
Of course you could measure the memory usage of LabVIEW to see whether or not you are even hitting the 2GB limit. If that is the case then it would be beneficial to use 64-bit LabVIEW instead of 32-bit LabVIEW to have access to more memory on the PC. The USB3.0 ports should not be the limiting factor given each port has a 400MB/s bandwidth. This means the bottleneck must be either memory usage and/or your programs implementation.
I appreciate your comment on the AVI Creation VI. The AVI Creation VI is called every loop to acquire a new video, which is not overwriting the old video. it creates a new one with a new name regulated by the iteration counter "i". This loop only iterates after acquiring a video, which will be every ~10 minutes (it is regulated by the minutes/trial control so that I can set it to 1 minutes for testing the program. I only need a couple seconds to see it is running slow and verify with a short video). It seems that this functions as expected and while it is probably not the only way to do it, it is not the cause of my particular issue, although I see a difference with the example in that I call "IMAQ Create" a second time. I deleted this a ran the main code with no difference.
To restate my problem, when writing frames to the video using the avi Write2 function, I cannot manage to acquire frames from four cameras at 10 fps. The bottleneck seems to be from memory to hardrive as far as I can tell. A suggestion might be blocking out memory to be written, then writing it in memory, then transferring it to the hard drive upon closing the avi? Similarly when coding large arrays/matrices, defining the size and writing every iteration is more efficient than increasing the size every iteration. I am not sure how to implement this...
To expand upon the example provided and why it doesnt work. Forgive me if this is incorrect but because I am running LabVIEW 2013 I could not directly open the example so I found it in an older version, we could be talking about completely different things if this example was changed between 2013 and 2014. However in the 2013 version, this vi is not for USB cameras as it uses IMAQ not IMAQdx. Additionally, the loop iteration is controlled by the camera acquisition. I have tried many times to override this, but it is not possible with mere timed loops and "wait for next ms". The camera acquisition cannot be changed from 30 fps (even with property nodes I have tried several methods). The write function is called every iteration when grab is called, at 30 fps. Running this for 10 minutes hits the 2 GB limit for 32 bit. Additionally coding is required to lower the writing rate in order to stay under 2 GB, and at this point it is no longer a straight forward/ efficient example. I can either remove the write function and place it in an independent loop as I did with my code, or write every third loop iteration. Writing in a seperate loop in my under qualified opinion has the benefit of not slowing down the grab function with writing functions that seem to be slowing things down.
I do not have a decent 64-bit computer that has room for the PCIe-8244. While purchasing a new computer might solve the problem I would like to try and solve this by implementing some software modifications.
Codec being used is Microsoft Video 1, available I have this list:
Microsoft Video 1
Intel IYUV codec
Cinepak Codec by Radius
Indeo video 5.11
FF Video Codec 1 (FFV1) (NI Vision)
Motion JPEG (NI Vision)
Y800 Uncompressed Grey Scale (NI Vision)
YUV 4:2:0 Planar (NI Vision)
To reduce the amount of loops I have for now I combined all of the Grab loops into one while loop and this runs smoothly, it is at least a bit more condensed. I am trying now to reduce the 4 frame saving loops into one loop and giving each camera its own "state machine" architecture within that loop to see if it makes a difference. So far it looks prettier but still runs the frame saving loop slowly.