Batch process AVI files into PNG/JPG

조회 수: 10 (최근 30일)
Louise Wilson
Louise Wilson 2019년 7월 8일
댓글: Edric Ellis 2019년 7월 9일
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
Louise Wilson
Louise Wilson 2019년 7월 8일
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 2019년 7월 9일
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

댓글을 달려면 로그인하십시오.

답변 (1개)

Image Analyst
Image Analyst 2019년 7월 9일
Put your existing code inside the for loop of the FAQ.
  댓글 수: 1
Louise Wilson
Louise Wilson 2019년 7월 9일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Startup and Shutdown에 대해 자세히 알아보기

제품


릴리스

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by