If you're interested in frame-based visualization, here's a must-have function. You may have video frames that you want to analyze, and do some processing and visualization on every frame. Once that's all done, you may want to be able to quickly flip through the frames or view them as a movie. Joao's videofig allows you to do just that.
You first set up your function that would be applied to any particular frame. This function should include any visualization as well. Here's an example that performs edge detection and displays an overlayed image of a frame from a video object. One of the input arguments must be the frame number.
function redraw(frame, vidObj) % REDRAW Process a particular frame of the video % REDRAW(FRAME, VIDOBJ) % frame - frame number to process % vidObj - VideoReader object % Read frame f = vidObj.read(frame); % Get edge f2 = edge(rgb2gray(f), 'canny'); % Overlay edge on original image f3 = bsxfun(@plus, f, uint8(255*f2)); % Display image(f3); axis image off end
videofig takes two input arguments:
- Total number of frames
- Function handle to a function that should be called for each frame. This function should only take one input argument, "frame number". If your function takes additional arguments, use an anonymous function as shown below.
Note: "rhinos.avi" is a movie file that ships with Image Processing Toolbox. VideoReader is a new class introduced in R2010b that replaces mmreader (introduced in R2007b). If you are using an older version (pre-R2010b), replace VideoReader with mmreader.
vid = VideoReader('rhinos.avi'); % Set up video figure window videofig(vid.NumberOfFrames, @(frm) redraw(frm, vid)); % Display initial frame redraw(1, vid);
That's it! You now have an interactive video player that allows you to view the frames. As you can see, the figure has a scroll bar at the bottom that you can click and drag. You can also control the video via the keyboard, such as with the arrow keys.
I would also like to point out some of Joao's nice coding practices.
- Input argument validation to ensure proper operation of the function. He uses assert to check for argument conditions. I would also recommend taking a look at inputParser and validateattributes for this purpose.
- Nested functions to manage data. These are especially useful when you want to change the states as the user interacts with the tool.
- Timer object to control playback of video. I find timers (as opposed to loops) to be more useful for animation/playback applications, since I can easily stop the animation by stopping the timer.
- Function handles for the redrawing function. This is the suggested method for providing functions as inputs, instead of passing in the string of the function name. Loren has a lot of useful posts on her blog.
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.