06-02-2015 03:19 PM
I have designed a VI using a state machine to configure, grab, and save a video stream to AVI. We are using LabView V14 on WindowsXP (yes, I know) with a Point Grey USB3 camera. We use this in our single-molecule biophysics experiments.
The intended design contains three states: Standby, Activate, and Record. Standby allows the user to configure the camera and image size. Activate initiates a grab and allows live modification of FPS and image offsets in order to properly frame the experiment. In the Record state, the VI should begin writing frames to uncompressed raw AVI. We use raw uncompressed AVI since we perform highly precise image processing on the images afterwards-- individual pixel intensity levels are very important.
The state machine seems to work well as I can cycle through the different states just fine. The Standby and Activate cases work as intended. However, there are two problems with the Record state....
1) The resulting AVI file only contains one image, the first frame grab. This is despite the fact that the Grab/Write loop is iterating-- I used an indicator to be sure. I modelled this loop after several code examples found online and I am coming up empty handed as to why this is happening.
2) At high frame rates (>30), the Grab and AVI2 Write loop will exit spontaneously after some time. I have observed that tt high frame rates the buffer seems to grow at a larger rate than the loop iteratations, i.e. it is acquiring images into buffer quicker than the loop is executing. I do not know if this is the source of the problem, or perhaps it might be related to both problems-- or maybe even a third problem entirely that also needs fixing.
I have attached snippets for the Activate and Record cases and I would appreciate any assistance. Thanks!
06-02-2015 04:03 PM
In our case, we were watching mice, but it is otherwise similar -- camera recording at 30fps, a trigger to start recording AVIs (I don't recall right now if they were compressed or not).
We used a Producer/Consumer loop -- the camera (your State Machine) was the Producer, and when it stored frames, it really put the Image on a Queue. The Consumer was responsible for opening the AVI, writing frames, and closing the AVI. I'm pretty sure the Consumer was also a State Machine (or maybe an Action Engine), as it had the responsibility for not only writing, but opening/closing the AVIs.
Something to think about is the number of buffers in your Camera. You need enough (what does that mean? I'll try to explain, to the best of my understanding ...)
As I understand it, the Camera Driver reserves a bunch of memory somewhere for storing images. This "buffer" is arranged in a circular fashion, so if there are 6 buffers, they will be filled 1, 2, 3, 4, 5, 6, 1, 2, 3, ... At 30 fps, therefore, it will take 1/5 second before you start overwriting your images. When you pass an "image" in IMAQdx, you are really passing a pointer to one of these buffers (that, I believe, is why you need to create a new IMAQ image in order to manipulate existing images -- you need to allocate storage space).
So your camera is recording, and you decide to start saving images in an AVI. You start passing "images", pointers to buffers, to the AVI writing routine. It's in a Queue, which has some buffer space of its own -- say your Queue has a fixed length of 100. You might think you could store the last 100 images, but you can't -- you can only store the last 100 pointers to images, which after 6 (the number of buffers in the camera), start to repeat. So if it take more than 200 msec to start emptying the image Queue into the AVI file, you will "lose" images unless you increase your buffer size.
Bob Schor
06-03-2015 10:31 AM
Hi Bob,
Thanks for the reply. I actually had a previous architecture that would be similar to the producer/consumer you describe, but I was unable to get the booleans to operate in the manner I desired (activating and deactivating the camera and AVI write separately, allowing repeated image resizing without exiting the VI, etc). The current design I am using works quite well as far as allowing the user to perform the desired actions. Additionally, I figure that having one loop running at a time should be advantageous over two (or more) simultaneously running loops. The only thing that does not seem to work is the Grab and Write to AVI loop.
I am somewhat familiar with the concept of buffers, but the high-level IMAQdx VIs do not seem to have any method of altering buffer functions in detail... so I gather that the high-level VIs are intended to automatically optimise the buffer situation. I suppose I could attempt to build the VI using the low-level IMAQdx VIs, but several other example VIs I've looked at seem to work fine with the high-level solutions; my Grab and Write loop is largely similar to examples from NI and forum snippets.
Nonetheless, I will attempt to replace the high-level IMAQdx VIs with a design based on low-level IMAQdx VIs so that I can manipulate the buffer parameters and see what happens.
06-03-2015 12:00 PM
@dcbiomed wrote:
Hi Bob,
Additionally, I figure that having one loop running at a time should be advantageous over two (or more) simultaneously running loops. The only thing that does not seem to work is the Grab and Write to AVI loop.
OK, so I lied. For each mouse, we had probably a half-dozen (maybe more!) loops running simultaneously. And we typically ran 24 mice at the same time (that's a lot of loops, made us sort of loopy). As long as you are not running LabVIEW 7.0 on a Pentium III PC running Windows 98, you should be OK having, say, 5 loops ...
BS