Creating Time-Lapse Video Using Timer Events
This example shows how to create a time-lapse video using timer events to prequalify frames.
The Image Acquisition Toolbox™ makes it easy to produce time-lapse video. In this example, we will use timer events to acquire frames to an AVI file. This technique of time decimation has the advantage that it allows you to make a decision about each frame before storing it. An application of this would be to only store frames that meet certain illumination levels, have motion relative to the previous frame, etc.
Watch a day long time-lapse sequence. (21 seconds)
% Add the callback function directory to the MATLAB® path. utilpath = fullfile(matlabroot, 'toolbox', 'imaq', 'imaqdemos', 'helper'); addpath(utilpath);
Before acquiring images using the Image Acquisition Toolbox, create a video input object.
% When executing the following code, you may need to % modify it to match your acquisition hardware. vid = videoinput('winvideo',1,'RGB24_352x288');
To generate timer events, we specify two things: what happens when it occurs, and how often it should occur. The TimerFcn property specifies the callback function to execute when a timer event occurs. A timer event occurs when the time period specified by the TimerPeriod property expires.
The callback function is responsible for triggering the acquisition and storing the frame into the AVI file. More details on how to use this callback can be found in the documentation. This callback function itself is defined in the file timelapse_timer.m
The configuration we will use is
- timelapse_timer will execute each time the timer elapses
- The timer function will execute every one second
set(vid,'TimerPeriod',1); vid.TimerFcn = @timelapse_timer;
Store the VideoWriter object in the UserData property of the video input object so that it will be available inside the callback.
vwObj = VideoWriter('timelapsevideo', 'Uncompressed AVI'); vwObj.FrameRate = 15; open(vwObj);
Each time the timer event occurs
- Manually trigger the acquisition using the triggerconfig command
- Acquire one frame
- Acquire 9 additional triggers worth of data, for a total of 10 frames
triggerconfig(vid, 'manual'); vid.FramesPerTrigger = 1; vid.TriggerRepeat = 9; vid
Summary of Video Input Object Using 'Logitech QuickCam Fusion'. Acquisition Source(s): input1 is available. Acquisition Parameters: 'input1' is the current selected source. 1 frames per trigger using the selected source. 'RGB24_352x288' video data to be logged upon START. Grabbing first of every 1 frame(s). Log data to 'memory' on trigger. Trigger Parameters: 10 'manual' trigger(s) upon TRIGGER. Status: Waiting for START. 0 frames acquired since starting. 0 frames available for GETDATA.
Now, start the time lapse acquisition, and wait for up to 20 seconds for the acquisition to complete.
Once the capture is completed, retrieve the VideoWriter object stored in the UserData property, and use the close function to release the resources associated with it.
avi = vid.UserData; avi = close(avi);
To play back the time-lapse AVI sequence, right-click on the filename in the MATLAB® Current Folder browser, and choose Open Outside MATLAB from the context menu.
When you are done with the video input object, you should use the delete function to free the hardware resources associated with it, and remove it from the workspace using the clear function.
delete(vid); clear vid;
The following is a description of the callback function executed for each timer event
- Trigger the toolbox to acquire a single frame
- Retrieve the frame
- Determine whether to keep the frame
- Use the writeVideo function to add the frame to the AVI file
The VideoWriter object is stored in the UserData property of the object.
function timelapse_timer(vid,~) % This callback function triggers the acquisition and saves frames to an AVI file. % trigger the acquisition and get the frame trigger(vid); frame = getdata(vid,1); % Retrieve the total number of frames acquired numframes_acquired = vid.FramesAcquired; % Drop every other frame: If the frame is odd, % keep it. If it is an even frame, do not keep it. keepframe = (mod(numframes_acquired,2) == 1); % Insert your processing code here if(~keepframe) return; end % Retrieve the VideoWriter object stored in the UserData % property. vwObj = vid.UserData; % Add the frame to the AVI writeVideo(vwObj, frame); end