MATLAB Answers

Batch process AVI files into PNG/JPG

8 views (last 30 days)
Louise Wilson
Louise Wilson on 8 Jul 2019
Commented: Edric Ellis on 9 Jul 2019
Hi all,
I am working with a large dataset of .avi files which I need to split into .png for further analysis. From previous questions on here, I've derived some code which is doing this quite nicely for one avi file:
clc;
clear;
%Set current directory to folder containing this m file
cd('C:\Users\...');
%Open file to be converted
movieFullFileName = fullfile(cd, '26032019.AVI');
%Read in avi file
videoObject = VideoReader(movieFullFileName)
%Get some info from avi file
[folder, baseFileName, extentions] = fileparts(movieFullFileName);
%Create output folder:
folder=pwd;
outputFolder = sprintf('%s/Frames', folder);
%Determine how many frames there are
numberOfFrames = videoObject.NumberOfFrames;
vidHeight = videoObject.Height;
vidWidth = videoObject.Width;
for x=1 : numberOfFrames
frame = read(videoObject,x)
outputBaseFileName = sprintf('-%4.4d.png', x); %output filename, each frame numbered from 0001
outputFullFileName = fullfile(outputFolder, strcat(baseFileName, outputBaseFileName)); %output filename
imwrite(frame, outputFullFileName, 'png'); %write output file
end
At the moment, I'm only converting one video file and it takes just over a minute to process which seems quite long. Once I am finished collecting my data I'll have over 1500 videos so I am wondering if, at this early stage, there is anything I can do to refine or speed up my code?
Secondly, I would like to introduce another for loop which lets me apply this code to a series of avi files within a folder. Can anyone point me in the right direction with this?
Thanks!!

  6 Comments

Show 3 older comments
Louise Wilson
Louise Wilson on 8 Jul 2019
Thank you Edric! I did what you said and removed the outer loop, and now it works without problems, and is much faster!!
However, now I am only looping through multiple files within one folder. If possible, I was hoping to loop through many folders/paths? So, for example, I would list a series of C:/ destinations within paths. And then the loop would loop through these paths... does it make sense?
Louise Wilson
Louise Wilson on 8 Jul 2019
Hi Edric, I'm also curious about the code as it plays back the video to get each frame, am I correct? Is it possible to do similar but without this... so to speed up the code? I am looking at readframe but not understanding it:https://au.mathworks.com/help/matlab/ref/videoreader.readframe.html
Edric Ellis
Edric Ellis on 9 Jul 2019
To loop over multiple folders, the simplest way is to use an outer loop like this:
videoFolders = {'c:\path\to\folder\one', 'c:\path\to\folder\two'};
for folderIdx = 1:numel(videoFolders)
thisFolder = videoFolders{folderIdx};
theseFiles = dir(fullfile(thisFolder, '*.avi'));
for fileIdx = 1:numel(theseFiles)
... % process each file in the folder
end
end
Another option if there's a common root folder, and you're using a recent version of MATLAB, is to use the '**' syntax in the dir command, like this:
commonVideoFolder = 'c:\root\path\to\videos';
allFiles = dir(fullfile(commonVideoFolder, '**', '*.avi'));
for fileIdx = 1:numel(allFiles) % could be 'parfor'
thisEntry = allFiles(fileIdx);
thisFileName = fullfile(thisEntry.folder, thisEntry.name);
% ... process the file.
end

Sign in to comment.

Answers (1)

Image Analyst
Image Analyst on 9 Jul 2019
Put your existing code inside the for loop of the FAQ.

  1 Comment

Louise Wilson
Louise Wilson on 9 Jul 2019
Hi! Thank you! I have my code working for lots of *.avi files... but I want to run through many folders of avi files. Should I adapt the code in the link you mention to include a series of folders?
% Specify the folder where the files live.
myFolder = 'C:\Users\yourUserName\Documents\My Pictures'; %other folders here???
% Check to make sure that folder actually exists. Warn user if it doesn't.
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.jpg'); % Change to whatever pattern you need.
theFiles = dir(filePattern);
for k = 1 : length(theFiles)
baseFileName = theFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
% Now do whatever you want with this file name,
% such as reading it in as an image array with imread()
imageArray = imread(fullFileName);
imshow(imageArray); % Display image.
drawnow; % Force display to update immediately.
end
My code right now:
%%08 July 2019, Louise Wilson
%Code to split several .avi files within a folder into many .jpg files.
%Adapting code to use vision.VideoFileReader might be faster?
clc;
clear;
%Set current directory to folder containing this .m file and raw .avi files:
paths=cd('C:\Users\lwil634\...');
mkdir Frames %create Frames output folder
d=dir(fullfile(paths, '*.AVI')); %filename of each file to be processed
fileCount=length(d); %number of files to be processed
for j=1:fileCount
vidfile=d(j).name; %get name of jth video file
videoObject=VideoReader(vidfile); %read in avi file
[folder, baseFileName, extentions] = fileparts(vidfile); %get info from avi file
folder=pwd; %print working directory
outputFolder = sprintf('%s/Frames', folder); %put outfiles files in 'Frames' folder
%Determine how many frames there are
numberOfFrames = videoObject.NumberOfFrames;
vidHeight = videoObject.Height;
vidWidth = videoObject.Width;
for x=1 : numberOfFrames
frame = read(videoObject,x);
outputBaseFileName = sprintf('-%4.4d.png', x); %output filename, each frame numbered from 0001
outputFullFileName = fullfile(outputFolder, strcat(baseFileName, outputBaseFileName)); %full output filename with .avi file number
imwrite(frame, outputFullFileName, 'png'); %write output png file
end
end

Sign in to comment.

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!