How to extract frames of a video

459 次查看(过去 30 天)
Hi everyone! How can I extract frames of a video in matlab if I have used mmreader to read the video.I have used frame2im command but its not working.
  2 个评论
msp 2013-4-28
how to extract only key frames from the video ??
chao dong
chao dong 2016-5-30
I also need to extract pictures from video files, but it seems to me that format is critical towards this process.



Walter Roberson
Walter Roberson 2012-9-22
obj = mmreader(FileName);
video =;
Then, frame #K is video(:,:,:,K)
  14 个评论
Walter Roberson
Walter Roberson 2021-3-17
NumberOfFrames was historically a correct property names; it was since replaced with NumFrames .
The difference between NumberOfFrames and NumFrames is that NumberOfFrames involved MATLAB scanning the entire file at the time the VideoReader object was created, so NumberOfFrames was an accurate frame count, whereas NumFrames was an estimated count that did not involve scanning the entire stream. This made NumFrames much more efficient to get started with.
Using duration * Framerate is only an estimate, and fails under a couple of circumstances:
  • variable frame rate movies
  • if the stored FrameRate has been rounded, as is common for NTSC (people often specify 30 fps, or 29.9, or (when they try to be more accurate) 29.97 fps, but the true frame rate is slightly higher than 29.97)
  • Frame rates are stored in several file formats as the ratio of two integers, but the range of values allowed does not permit sufficient precision to be frame accurate after longer sequences
  • embedded devices are permitted by the standards to use frame rate calculations using limited precision, so that they do not need a full floating point cores, and can use much much less processor intensive fixed-point cores instead
Because of this, if you need an accurate count of frames, you need to count the frames instead of calculating how many there are.
Hazem El-Alfy
Hazem El-Alfy 2021-3-17
Great rebuttal of my earlier comment. I would rather not delete it for others to understand how not to address this issue.


更多回答(7 个)

Image Analyst
Image Analyst 2012-9-22
See my demo for extracting and measuring an AVI file (the standard MATLAB rhinos.avi movie):
% Demo macro to extract frames and get frame means from an avi movie
% and save individual frames to separate image files.
% Also computes the mean gray value of the color channels.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 14;
% Change the current folder to the folder of this m-file.
% (The line of code below is from Brett Shoelson of The Mathworks.)
% Open the rhino.avi demo movie that ships with MATLAB.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
movieFullFileName = fullfile(folder, 'rhinos.avi');
% Check to see that it exists.
if ~exist(movieFullFileName, 'file')
strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new one, or cancel', movieFullFileName);
response = questdlg(strErrorMessage, 'File not found', 'OK - choose a new movie.', 'Cancel', 'OK - choose a new movie.');
if strcmpi(response, 'OK - choose a new movie.')
[baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
if ~isequal(baseFileName, 0)
movieFullFileName = fullfile(folderName, baseFileName);
movieInfo = aviinfo(movieFullFileName)
mov = aviread(movieFullFileName);
% movie(mov);
% Determine how many frames there are.
numberOfFrames = size(mov, 2);
numberOfFramesWritten = 0;
% Prepare a figure to show the images in the upper half of the screen.
screenSize = get(0, 'ScreenSize');
newWindowPosition = [1 screenSize(4)/2 - 70 screenSize(3) screenSize(4)/2];
set(gcf, 'Position', newWindowPosition); % Maximize figure.
% set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
% Ask user if they want to write the individual frames out to disk.
promptMessage = sprintf('Do you want to save the individual frames out to individual disk files?');
button = questdlg(promptMessage, 'Save individual frames?', 'Yes', 'No', 'Yes');
if strcmp(button, 'Yes')
writeToDisk = true;
% Extract out the various parts of the filename.
[folder, baseFileName, extentions] = fileparts(movieFullFileName);
% Make up a special new output subfolder for all the separate
% movie frames that we're going to extract and save to disk.
% (Don't worry - windows can handle forward slashes in the folder name.)
folder = pwd; % Make it a subfolder of the folder where this m-file lives.
outputFolder = sprintf('%s/Movie Frames from %s', folder, baseFileName);
% Create the folder if it doesn't exist already.
if ~exist(outputFolder, 'dir')
writeToDisk = false;
% Loop through the movie, writing all frames out.
% Each frame will be in a separate file with unique name.
meanGrayLevels = zeros(numberOfFrames, 1);
meanRedLevels = zeros(numberOfFrames, 1);
meanGreenLevels = zeros(numberOfFrames, 1);
meanBlueLevels = zeros(numberOfFrames, 1);
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisFrame = mov(frame).cdata;
% Display it
hImage = subplot(1,2,1);
axis square;
caption = sprintf('Frame %4d of %d.', frame, numberOfFrames);
title(caption, 'FontSize', fontSize);
drawnow; % Force it to refresh the window.
% Write the image array to the output file, if requested.
if writeToDisk
% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
% Stamp the name and frame number onto the image.
% At this point it's just going into the overlay,
% not actually getting written into the pixel values.
text(5, 15, outputBaseFileName, 'FontSize', 20);
% Extract the image with the text "burned into" it.
frameWithText = getframe(gca);
% frameWithText.cdata is the image with the text
% actually written into the pixel values.
% Write it out to disk.
imwrite(frameWithText.cdata, outputFullFileName, 'png');
% Calculate the mean gray level.
grayImage = rgb2gray(thisFrame);
meanGrayLevels(frame) = mean(grayImage(:));
% Calculate the mean R, G, and B levels.
meanRedLevels(frame) = mean(mean(thisFrame(:, :, 1)));
meanGreenLevels(frame) = mean(mean(thisFrame(:, :, 2)));
meanBlueLevels(frame) = mean(mean(thisFrame(:, :, 3)));
% Plot the mean gray levels.
hPlot = subplot(1,2,2);
hold off;
plot(meanGrayLevels, 'k-', 'LineWidth', 2);
hold on;
plot(meanRedLevels, 'r-');
plot(meanGreenLevels, 'g-');
plot(meanBlueLevels, 'b-');
% Put title back because plot() erases the existing title.
title('Mean Gray Levels', 'FontSize', fontSize);
if frame == 1
xlabel('Frame Number');
yLabel('Gray Level');
% Get size data later for preallocation if we read
% the movie back in from disk.
[rows columns numberOfColorChannels] = size(thisFrame);
% Update user with the progress. Display in the command window.
if writeToDisk
progressIndication = sprintf('Wrote frame %4d of %d.', frame, numberOfFrames);
progressIndication = sprintf('Processed frame %4d of %d.', frame, numberOfFrames);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
% Alert user that we're done.
if writeToDisk
finishedMessage = sprintf('Done! It wrote %d frames to folder\n"%s"', numberOfFramesWritten, outputFolder);
finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
disp(finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.
% Exit if they didn't write any individual frames out to disk.
if ~writeToDisk
% Ask user if they want to read the individual frames from the disk,
% that they just wrote out, back into a movie and display it.
promptMessage = sprintf('Do you want to recall the individual frames\nback from disk into a movie?\n(This will take several seconds.)');
button = questdlg(promptMessage, 'Recall Movie?', 'Yes', 'No', 'Yes');
if strcmp(button, 'No')
% Read the frames back in, and convert them to a movie.
% I don't know of any way to preallocate recalledMovie.
for frame = 1 : numberOfFrames
% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);
% Read the image in from disk.
thisFrame = imread(outputFullFileName);
% Convert the image into a "movie frame" structure.
recalledMovie(frame) = im2frame(thisFrame);
% Get rid of old image and plot.
% Create new axes for our movie.
subPlot(1, 3, 2);
axis off; % Turn off axes numbers.
title('Movie recalled from disk', 'FontSize', fontSize);
% Play the movie in the axes.
% Note: if you want to display graphics or text in the overlay
% as the movie plays back then you need to do it like I did at first
% (at the top of this file where you extract and imshow a frame at a time.)
msgbox('Done with this demo!');
catch ME
% Some error happened if you get here.
stError = lasterror;
strErrorMessage = sprintf('Error extracting movie frames from:\n\n%s\n\nError: %s\n\n)', movieFullFileName, stError.message);
  9 个评论
Image Analyst
Image Analyst 2014-8-14
So change it John. The filename is hard coded in there to be one of the standard video demos that ship with MATLAB:
movieFullFileName = fullfile(folder, 'traffic.avi');
Just change it to whatever you want. It can be an mp4 file or whatever.
John 2014-8-14
My mistake... The drop down that shows up when searching for the file was not set to "all files" but was set to "avi" and I didn't realize it.
But, I did change the code to adapt to the location of the file. I may be a little slow sometimes, but that's one thing I did catch when looking through the code. :)


Sushil  Sharma
Sushil Sharma 2019-10-15
Upadte answer
In the lestest veriosn of matlab, we have to use VideoReader instead of mmreader,then you are able to convert any video file into a frames
Here the simple of code to get the frames
%% Change .avi format to images frames
obj = VideoReader('test2.avi');
vid = read(obj);
frames = obj.NumberOfFrames;
for x = 1 : frames
  3 个评论
Image Analyst
Image Analyst 2022-7-20
@krishna Chauhan looks like your file may be empty. Can you attach it in a new question? For some reason they changed the number of frames name from NumberOfFrames to NumFrames. Make sure you're using the right one. I'm attaching my latest movie demos.
If you have any more questions, then, in your new discussion thread, attach your data and code to read it in with the paperclip icon after you read this:
Walter Roberson
Walter Roberson 2022-7-20
NumFrames has a slightly different semantics than NumberOfFrames . The older NumberOfFrames was initialized when the file was opened, by reading the entire file to get the exact number of frames. The newer NumFrames is estimated at the time the video is opened, based upon file size and nominal frame rate, but will be corrected if you read to end of video.
NumberOfFrames was trustable but slow and was overhead that was incurred for every video even when you did not need it.
NumFrames is not trustable but is fast; if you need to know the exact actual number of frames you have to read the file through.


dan kin
dan kin 2019-12-12
How can I add a legend like this Redline - meanRed, Blueline - meanBlue, ... to the subplot(2, 2, 2)?
  2 个评论
Sushil  Sharma
Sushil Sharma 2019-12-12
legend('real angle', 'estimate angle')
Image Analyst
Image Analyst 2019-12-12
See my attached demo, ExtractMovieFrames.m.
You can also use text() instead of legend() if you want more precise control over where the legend appears.


msp 2013-4-28
how to extract only key frames from the video ??
  2 个评论
ameet kumar
ameet kumar 2016-1-30
There is an error when I used the 'movie2avi' it cannot generate avi file in matlab R2013 so kindly help me what can I do?
Walter Roberson
Walter Roberson 2016-1-30
We need to know the error message. But you already asked this as a Question so the discussion should go there


Ameni chetouane
Ameni chetouane 2019-6-27
I have read frames with VideoReader,but i don'i get the exact number of frames that contain the video.
the number of frames of the video is 400 but readFrame return only 200 frames.
Does any one have solution to this problem?
% Set up video reader and player
videoFile = 'copie2.avi';
videoReader = VideoReader(videoFile);
iStop = []; % Stop the frame display if this is not empty
fps = get(videoReader, 'FrameRate');
disp(fps); % the fps is correct: it's the same declared in the video file properties
while hasFrame(videoReader)& isempty(iStop)
%%for i=0:videoReader.Duration-1
%% videoReader.CurrentTime=i;
iStop = input('0 to stop, return to continue');

Ely Raz
Ely Raz 2019-12-16
How can I add the possibility to select a ROI in Image Analyst script and analyzed it?
  1 个评论
Image Analyst
Image Analyst 2019-12-16
You can call imcrop() if you want a rectangular sub-image. If you want an irregularly-shaped region, see my attached demos.


Aayush Gupta
Aayush Gupta 2021-5-23
编辑:Walter Roberson 2021-5-23
%to read all the frames
% for reading any particular nth frame you can use read(v, n) or for reading a set of frames from 1 to 50 use read(v, [1,50])
%Note that these frames are particular 4Dimebsional uint8 code of a block
% to form an image or a still out from the frames use the code given below
images=reshape(frames, 360, 540, 3, num)
%here using the command imshow(frames(:, :, :, 1)) get the dimensions of one particular still which is (360x540x3) in my case
%Now images will be the collection of all stills present in the video filename.mp4
%use imshow(images(:, :, :, 1)) to view the first still
  1 个评论
Walter Roberson
Walter Roberson 2021-5-23
If you have done frames=read(v) then you can use
num = size(fraems,4);
There is no benefit to doing the reshape(): it only leads to problems if your frames are not each 360 x 540 x 3. Just using read() is enough to get the frames as H x W x 3 x num



Help CenterFile Exchange 中查找有关 Image Processing and Computer Vision 的更多信息



Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by