Batch process AVI files into PNG/JPG
Show older comments
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
Louise Wilson
on 8 Jul 2019
KALYAN ACHARJYA
on 8 Jul 2019
it runs forever, and doesn't stop until I ctrl+c.
Please check on
- length(paths)
- length(d)
- numberOfFrames
Do confirm?
Edric Ellis
on 8 Jul 2019
I think what's going wrong here is the outer-most loop. This code:
paths = cd('...');
returns in paths a char-vector of the old working directory, which will be something like 'c:\my\old\working\directory'. Because paths is a vector of type char, the outermost loop is simply repeating the processing multiple times doing exactly the same thing each time - once per character in paths. This is not what you want! To fix, simply omit the outermost loop.
I'm not familiar with video processing - but I am familiar with parallel computing - so one thought might be (if you have Parallel Computing Toolbox available) to convert the loop over the video files to be a parfor loop. Therefore, your code might look like this:
videoDir = 'C:\Users\lwil634\Documents\Cameras\Test';
videoFiles = dir(fullfile(videoDir, '*.avi'));
parfor fIdx = 1:numel(videoFiles)
thisVideoFile = fullfile(videoDir, videoFiles(fIdx).name);
% process thisVideoFile...
end
Louise Wilson
on 8 Jul 2019
Louise Wilson
on 8 Jul 2019
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
Answers (1)
Image Analyst
on 9 Jul 2019
0 votes
Put your existing code inside the for loop of the FAQ.
1 Comment
Louise Wilson
on 9 Jul 2019
Categories
Find more on Loops and Conditional Statements in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!