For various reasons, I've been spending a lot of time working with videos in MATLAB lately--whether helping a customer work through some challenges, or developing new tools for detecting, tracking, and labeling regions of interest in individual frames. Getting started with video analysis can be a bit daunting--there are several options to confound the newer user, and it's easy to take mis-steps en route.
I particularly like Image Analyst's tutorial precisely because (as one recent commenter put it), it's: "a nice starting place for video processing. Shows how easy it is for beginners to get into. Great job!"
The tutorial is at just the right level to show video playback, and to demonstrate how to incorporate a simple frame-wise processing algorithm. Using a demo video ('rhinos.avi') that ships with the Image Processing Toolbox, Image Analyst shows how to:
- Extract the folder information for the target video:
folder = fileparts(which('rhinos.avi'));
- Select a video from that directory:
movieFullFileName = fullfile(folder, 'rhinos.avi');
- Create a video reader:
videoObject = VideoReader(movieFullFileName)
- And use it to read and display frames. (I show the code with slight modifications here):
fontSize = 12; numberOfFrames = videoObject.NumberOfFrames; for frame = 1 : numberOfFrames thisFrame = read(videoObject, frame); image(thisFrame); caption = sprintf('Frame %4d of %d.', frame, numberOfFrames); title(caption, 'FontSize', fontSize); end
There's much more.... Image Analyst shows the user the how to calculate and plot live statistics for the frame, and to perform some basic image analyses during the read/display process, and to visualize the results while the video plays:
Optionally, you are prompted to write individual frames as images to a directory, and to recall them for subsequent playback. Very useful stuff!
I have a few suggestions for consideration:
Image Analyst's video player uses "frame-based" reading. In R2014b, we introduced "time-based" frame reading that can be more efficient. To modify the code to use time-based reading, consider commenting out the call to videoObject.NumberOfFrames. (That triggers frame-based reading, and causes an error if you subsequently try to read using time-based modalities.) Instead, you can calculate the number of frames using numberOfFrames = round(videoObject.FrameRate * videoObject.Duration);, if you need to.
Then, instead of
for frame = 1:numberOfFrames
you can use a while loop:
and a new readFrame command.
Also, I really like imshow for displaying images. It recognizes that the input matrix is an image, and maintains the aspect ratio. (image-displayed images can be stretched.) It also suppresses axes tick marks automatically, and has some other nice behaviors. Moreover, once you've created an "image object," you can re-use it quite easily by modifying the "CData" of the object. There's no need to create a new image with each frame read:
videoObject = VideoReader(movieFullFileName); frame = readFrame(videoObject); img = imshow(frame); while hasFrame(videoObject) thisFrame = readFrame(videoObject); img.CData = thisFrame; caption = sprintf('Frame %4d of %d.', ... round(videoObject.CurrentTime*videoObject.FrameRate), numberOfFrames); title(caption, 'FontSize', fontSize); end
Image Analyst uses a struct to store the frame information. The new "image datastore" functionality (introduced in R2015b) facilitates easy reference to, and visualization of, individual images. (Image Analyst shows how to create a new video from the extracted frames, but you can alternatively just display them in a loop, using the readimage method of the datastore object. (I'll leave it to you to peruse the documentation for those new capabilities.)
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.