how save frames that exit from video in a specific folder
Show older comments
hi * i have this function that do extract video into frames,*
function [] = intoframe(inpath)
inpath=('clock.avi')
myVid= mmreader(inpath);
numFrames= myVid.NumberOfFrames;
i= 1;
while i<= numFrames
currentFrame= read(myVid,i);
combinedString=strcat(int2str(i-1),'.jpg');
imwrite(currentFrame,combinedString);
i=i+1;
end
end
how can save these frames into a specific folder
Answers (2)
Image Analyst
on 1 Mar 2012
See my demo:
Pay particular attention to these lines:
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')
mkdir(outputFolder);
end
OK, now here's the demo:
% 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.)
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
% 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);
else
return;
end
else
return;
end
end
try
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.
figure;
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')
mkdir(outputFolder);
end
else
writeToDisk = false;
end
% 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);
image(thisFrame);
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');
end
% 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);
end
% Update user with the progress. Display in the command window.
if writeToDisk
progressIndication = sprintf('Wrote frame %4d of %d.', frame, numberOfFrames);
else
progressIndication = sprintf('Processed frame %4d of %d.', frame, numberOfFrames);
end
disp(progressIndication);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
end
% Alert user that we're done.
if writeToDisk
finishedMessage = sprintf('Done! It wrote %d frames to folder\n"%s"', numberOfFramesWritten, outputFolder);
else
finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
end
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
return;
end
% 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')
return;
end
% 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);
end
% Get rid of old image and plot.
delete(hImage);
delete(hPlot);
% 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.
movie(recalledMovie);
% 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);
uiwait(msgbox(strErrorMessage));
end
1 Comment
Stephen23
on 20 Apr 2020
Note: the behavior of this format string is not documentated:
'Frame %4.4d.png'
The documented way to get leading zeros is simply:
'Frame %04d.png'
Hasti Hayati
on 6 Dec 2016
0 votes
Thanks guys
5 Comments
Devansh Shukla
on 9 Apr 2021
I had a couple of doubts,
1) Firstly, could you just explain me how many frames of images is your code dividing any video length? Like could you explain me the logicnof your code section :
% Determine how many frames there are.
numberOfFrames = videoObject.NumberOfFrames;
vidHeight = videoObject.Height;
vidWidth = videoObject.Width;
numberOfFramesWritten = 0;
2) And the second question, i had was that while saving the images into a sepearate folder , how or what should we change in the code section to assign it to a specific place where we want the folder to be created. Because curretnly i am struggling with saving the images in the same flder as the ".m file " which gets saved.
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')
mkdir(outputFolder);
end
else
All your help is really appreciated!
Thank You so much!
Image Analyst
on 9 Apr 2021
1) I don't know what this means: "how many frames of images is your code dividing any video length". What am I dividing? Dividing what by what? The values I get are just inherent properties of the video itself. Any video will of course have some lateral size of the images (width in pixels, height in pixels) and will of course have some number of frames in the video. Caution : at some release Mathworks changed NumberOfFrames to NumFrames or vice versa (apparently for no reason other than to make it complicated for us) so check on that so that you use the proper name.
2) outputFolder is the folder where the output images are to be stored. You can make it be whatever you want, such as
outputFolder = 'c:/my still frames';
or whatever you want.
Devansh Shukla
on 9 Apr 2021
Thank You So Much for your reply!
My question may be a bit silly and i am really sorry for that but i just want to get my thought clear.
So for my first question what i meant was , i have a video of the length of 52 secs and when i run your code i get 1049 image frames from the video. So i wanted to understand the math of it ?
Like why am i just getting just 1049 frame? Is it because that was the framerate (frames/sec) with which the video was captured ?
Also is there a way i can change the number of frames i can get from the video. Like for example i want 520 frames from my 52 seconds video which would mean 10 frames per second.
Like is there a way i can change the framerate and get the frames accordingly ?
Did it make sense ?
Devansh Shukla
on 9 Apr 2021
Also one more question, is this code of converting a video into image frames loseless ?
Image Analyst
on 9 Apr 2021
Edited: Image Analyst
on 9 Apr 2021
The number of frames is determined by how long it is and how many frames per second it is. You can write a new video with a different frame rate if you want.
I don't believe so. I think MP4 is a lossy format but I'm not sure.
Categories
Find more on Image Preview and Device Configuration in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!