You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Use images to create video, script to read through hundreds of folders to do it
10 views (last 30 days)
Show older comments
Hi,
Task: I have been tasked to come up with a MATLAB script that takes tiff images in a folder and creates a movie from them.
Details: There are hundreds of folders, each containing two subfolders, that contain hundreds of images each. I need the script to... >Go into folder 1 >Go into subfolder A >Create a video using the hundreds of images there and save it in the folder >Go back out to folder 1 >Go into subfolder B >Create video like above >Go back out and into folder 2 and so on until it has gone through all of the folders.
I know... this is a big job
Problems: I created a folder on my desktop and downloaded pictures of numbers 1-10 as samples. I found a script that will go into that folder and create a video from the images. But that's it. I don't know if the video is created or saved anywhere, and all the viewer shows is the single images that are in the folder.
Here's the code I used... found it on here and linked to a video explaining it.
clear all
close all
clc
framesPerSec = Enter #;
movie_name = ('Enter name');
aviobj = avifile(movie_name,'fps',framesPerSec);
dname = ('C/blah/blah);
top_file = [dname '\'];
ls_top_file = ls(top_file);
c = cellstr(ls_top_file);
cc = c(3:length(c));
S = size(cc);
a = 1;
while a <= S(1)
close all
file = char(cellstr([top_file char(cc(a))]));
data_n = char(cc(a))
file_name = char(cc(a));
figure
fileToRead2 = [dname '\' file_name];
imshow((fileToRead2))
axis tight
hold off
h = getframe(gcf);
aviobj = addframe(aviobj,h);
a = a+1;
end
h = getframe(gcf);
aviobj = addframe(aviobj,h);
aviobj = close(aviobj);
Any tips on where to look, as I'm sure there are bits to my question that have been asked on here before.
1 Comment
Jan
on 26 Aug 2013
The brute clearing header "clear all, close all, clc" reduces the power of the debugger for no real benefit.
Accepted Answer
Image Analyst
on 20 Aug 2013
And here's a demo to show you how to recurse into subfolders:
% Start with a folder and get a list of all subfolders.
% Finds and prints names of all PNG, JPG, and TIF images in
% that folder and all of its subfolders.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
% Define a starting folder.
start_path = fullfile(matlabroot, '\toolbox\images\imdemos');
% Ask user to confirm or change.
topLevelFolder = uigetdir(start_path);
if topLevelFolder == 0
return;
end
% Get list of all subfolders.
allSubFolders = genpath(topLevelFolder);
% Parse into a cell array.
remain = allSubFolders;
listOfFolderNames = {};
while true
[singleSubFolder, remain] = strtok(remain, ';');
if isempty(singleSubFolder)
break;
end
listOfFolderNames = [listOfFolderNames singleSubFolder];
end
numberOfFolders = length(listOfFolderNames)
% Process all image files in those folders.
for k = 1 : numberOfFolders
% Get this folder and print it out.
thisFolder = listOfFolderNames{k};
fprintf('Processing folder %s\n', thisFolder);
% Get PNG files.
filePattern = sprintf('%s/*.png', thisFolder);
baseFileNames = dir(filePattern);
% Add on TIF files.
filePattern = sprintf('%s/*.tif', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
% Add on JPG files.
filePattern = sprintf('%s/*.jpg', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
numberOfImageFiles = length(baseFileNames);
% Now we have a list of all files in this folder.
if numberOfImageFiles >= 1
% Go through all those image files.
for f = 1 : numberOfImageFiles
fullFileName = fullfile(thisFolder, baseFileNames(f).name);
fprintf(' Processing image file %s\n', fullFileName);
end
else
fprintf(' Folder %s has no image files in it.\n', thisFolder);
end
end
28 Comments
John
on 21 Aug 2013
Edited: John
on 21 Aug 2013
I'm fairly new to MATLAB, so please forgive my ignorance. :)
Regarding the linked discussion at the top of your post...
It seems that post details how to take a video that already exists and then processes it and outputs it to a new folder. I need to use the image files (tiff) that are in a folder and create a video from them.
Regarding the subfolder discussion here...
Does this take all the images in ALL of the folders then process them? I need the script to go into the subfolders and create the video using the images there, not take all of them from all folders and create one big video.
As I said, I'm a newbie so you may have already answered my question, I just don't know. I want to make sure I make sense in what I'm looking to do, which is hard to do by typing.
I want the script to go in this order, and it probably needs to be an overnight or weekend script. Some of the videos are already done and they are nearly one gig a piece, so with several hundred videos to do, it may take a while.
- Folder 1
- Subfolder A - contains 300 images, use these to make video and save in this folder.
- Subfolder B - contains 300 images, use these to make video and save in this folder.
- Folder 2
- Subfolder A - contains 300 images, use these to make video and save in this folder.
- Subfolder B - contains 300 images, use these to make video and save in this folder.
- Folder 3
- Subfolder A - contains 300 images, use these to make video and save in this folder.
- Subfolder B - contains 300 images, use these to make video and save in this folder.
- And so on until it goes through all the folders.
Thank you for any help. And I've learned alot just tinkering with the scripts you've linked to.
Image Analyst
on 21 Aug 2013
The first demo has two parts. One extracts all the frame from the video and writes them out as individual images. The second part reverses the process - it takes individual images off the disk and builds a video from them. It's the second part of the demo that you want since you already have the images on disk.
You then use the second code I gave you to find those images. It will recurse into all subfolders and find the images in each subfolder. Then you can take them, or whatever subset of them that you want, and add it to the video you are building up. No one says that you have to take every image you run across - you can use filters (say, filepatterns in dir() function) to get names of only files that you are interested in.
John
on 21 Aug 2013
Thanks for responding so quickly each time. I'll work on this for some time, probably several days, then I'll come back and thank you again when it all works out.
John
on 26 Aug 2013
Image Analyst
I have been working to combine the two scripts to do what's needed. The first script (define the starting folder, note subfolders, return a list of all image files in that folder) works flawlessly. When trying to combine it with the second script (use images to create video) it won't work.
This probably has something to do with my limited knowledge of MATLAB...
I get this error...
Undefined function or variable 'numberOfFrames'. Error in TEST (line 67) allTheFrames = cell(numberOfFrames,1);
Image Analyst
on 26 Aug 2013
You need to specify the number of frames you want to have in your video. Just count the image files you plan on putting into it.
John
on 26 Aug 2013
Also, I made some changes to the test folder I created on my computer to test the code, and now I'm getting another error. At first, I just had a folder with some images in it. Now, I created 2 subfolders within the folder and put images in them. When running the code again, it can tell me that there are 3 folders (main and 2 subs), but it says there are no images within the folder.
John
on 26 Aug 2013
Here's the code I used, if you want to look at it.
clear all
close all
clc
% Start with a folder and get a list of all subfolders.
% Finds and prints names of all PNG, JPG, and TIF images in
% that folder and all of its subfolders.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
% Define a starting folder.
start_path = fullfile(matlabroot, '\toolbox\images\imdemos');
% Ask user to confirm or change.
topLevelFolder = uigetdir(start_path);
if topLevelFolder == 0
return;
end
% Get list of all subfolders.
allSubFolders = genpath(topLevelFolder);
% Parse into a cell array.
remain = allSubFolders;
listOfFolderNames = {};
while true
[singleSubFolder, remain] = strtok(remain, ';');
if isempty(singleSubFolder)
break;
end
listOfFolderNames = [listOfFolderNames singleSubFolder];
end
numberOfFolders = length(listOfFolderNames)
% Process all image files in those folders.
for k = 1 : numberOfFolders
% Get this folder and print it out.
thisFolder = listOfFolderNames{k};
fprintf('Processing folder %s\n', thisFolder);
% Get PNG files.
filePattern = sprintf('%s/*.png', thisFolder);
baseFileNames = dir(filePattern);
% Add on TIF files.
filePattern = sprintf('%s/*.tif', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
% Add on JPG files.
filePattern = sprintf('%s/*.jpg', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
numberOfImageFiles = length(baseFileNames);
% Now we have a list of all files in this folder.
if numberOfImageFiles >= 1
% Go through all those image files.
for f = 1 : numberOfImageFiles
fullFileName = fullfile(thisFolder, baseFileNames(f).name);
fprintf(' Processing image file %s\n', fullFileName);
end
else
fprintf(' Folder %s has no image files in it.\n', thisFolder);
end
% Create a VideoWriter object to write the video out to a new, different file.
writerObj = VideoWriter('ExampleVideo.avi');
open(writerObj);
% Read the frames back in from disk, and convert them to a movie.
% Preallocate recalledMovie, which will be an array of structures.
% First get a cell array with all the frames.
allTheFrames = cell(numberOfFrames,9);
allTheFrames(:) = {zeros(vidHeight, vidWidth, 3, 'uint8')};
% Next get a cell array with all the colormaps.
allTheColorMaps = cell(numberOfFrames,1);
allTheColorMaps(:) = {zeros(256, 3)};
% Now combine these to make the array of structures.
recalledMovie = struct('cdata', allTheFrames, 'colormap', allTheColorMaps)
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);
% Write this frame out to a new video file.
writeVideo(writerObj, thisFrame);
end
close(writerObj);
% 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!');
end
Image Analyst
on 26 Aug 2013
So you're saying you said
numberOfImageFiles = whatever you did to calculate it....
and then when it got to the line
allTheFrames = cell(numberOfFrames,1);
it still said
Undefined function or variable 'numberOfFrames'.
Error in TEST (line 67) allTheFrames = cell(numberOfFrames,1);
Well, how did you calculate it? Is it still in scope when you get to where you try to use it?
John, do you know how to use the debugger to step through your code and examine the values of variables?
John
on 26 Aug 2013
No, I don't know how to use the debugger. I'll visit that link and watch the video to see what I can learn. As for your other questions, I'm not even sure what you're asking (newbie...)
John
on 26 Aug 2013
Watched the video... prior knowledge is obviously needed. It made sense, sorta, but I had a hard time following on some sections. I'm at a loss.
Image Analyst
on 26 Aug 2013
How about if you simplify it to just making the video by putting all your files into a single folder? At least you'll get that part out of the way. My demo shows you how to build up a video from a bunch of image files all in the same folder.
John
on 27 Aug 2013
It works!!!
I used the below code and tested it with test files with no problems. The only question I have now is how to set the resolution. How can I set it to be, say, 1280x960, or 640x480?
clear all
close all
clc
% Start with a folder and get a list of all subfolders.
% Finds and prints names of all PNG, JPG, and TIF images in
% that folder and all of its subfolders.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
% Define a starting folder.
start_path = fullfile(matlabroot, '\toolbox\images\imdemos');
% Ask user to confirm or change.
topLevelFolder = uigetdir(start_path);
if topLevelFolder == 0
return;
end
% Get list of all subfolders.
allSubFolders = genpath(topLevelFolder);
% Parse into a cell array.
remain = allSubFolders;
listOfFolderNames = {};
while true
[singleSubFolder, remain] = strtok(remain, ';');
if isempty(singleSubFolder)
break;
end
listOfFolderNames = [listOfFolderNames singleSubFolder];
end
numberOfFolders = length(listOfFolderNames)
% Process all image files in those folders.
for k = 1 : numberOfFolders
% Get this folder and print it out.
thisFolder = listOfFolderNames{k};
fprintf('Processing folder %s\n', thisFolder);
% Get PNG files.
filePattern = sprintf('%s/*.png', thisFolder);
baseFileNames = dir(filePattern);
% Add on TIF files.
filePattern = sprintf('%s/*.tif', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
% Add on JPG files.
filePattern = sprintf('%s/*.jpg', thisFolder);
baseFileNames = [baseFileNames; dir(filePattern)];
numberOfImageFiles = length(baseFileNames);
% Now we have a list of all files in this folder.
if numberOfImageFiles >= 1
% Go through all those image files.
for f = 1 : numberOfImageFiles
fullFileName = fullfile(thisFolder, baseFileNames(f).name);
fprintf(' Processing image file %s\n', fullFileName);
end
jpegFiles = dir(strcat(thisFolder,'\*.jpg'));
VideoFile=strcat(thisFolder,'\TestC');
writerObj = VideoWriter(VideoFile);
fps= 10;
writerObj.FrameRate = fps;
open(writerObj);
for t= 1:length(jpegFiles)
Frame=imread(strcat(thisFolder,'\',jpegFiles(t).name));
writeVideo(writerObj,im2frame(Frame));
end
close(writerObj);
else
fprintf(' Folder %s has no image files in it.\n', thisFolder);
end
end
Image Analyst
on 27 Aug 2013
Edited: Image Analyst
on 27 Aug 2013
Try using imresize before you add the image. If that works, please go ahead and mark this answer as Accepted.
John
on 28 Aug 2013
Can't make imresize work correctly. Can I not just use a function or something that sets the resolution to what I want it to be?
Walter Roberson
on 28 Aug 2013
In your loop near the end where you imread() and assign into Frame, after that line,
Frame = imresize(Frame, [1280, 960])
John
on 28 Aug 2013
That dind't actually change the resolution. All my videos are ending up as 830x820, which comes from the images themselves. And wouldn't that be trying to define Frame twice?
You have this
for t= 1:length(jpegFiles)
Frame = imread(strcat(thisFolder,'\',jpegFiles(t).name));
writeVideo(writerObj,im2frame(Frame));
Frame = imresize(Frame, [1280, 960]);
end
Walter Roberson
on 28 Aug 2013
Frame = imread(strcat(thisFolder,'\',jpegFiles(t).name));
Frame = imresize(Frame, [1280, 960]);
writeVideo(writerObj,im2frame(Frame));
Like I said, after you assign into Frame. Not after you write the frame out.
John
on 28 Aug 2013
Yeah it helps to put it in the right place. Image Analyst and Walter, thanks for the help!
John
on 11 Sep 2013
Having another problem with this... It works flawlessly for jpeg files, but when I try to change it to work with tif files, it gives an error. How would I need to change the code to allow it to work with tif files?
if numberOfImageFiles >= 1
for f = 1 : numberOfImageFiles
fullFileName = fullfile(thisFolder, baseFileNames(f).name);
fprintf(' Processing image file %s\n', fullFileName);
end
jpegFiles = dir(strcat(thisFolder,'\*.jpg'));
VideoFile=strcat(thisFolder,'\1280x960');
writerObj = VideoWriter(VideoFile);
fps= 1;
writerObj.FrameRate = fps;
open(writerObj);
for t= 1:length(jpegFiles)
Frame=imread(strcat(thisFolder,'\',jpegFiles(t).name));
Frame = imresize(Frame, [1280, 960]);
writeVideo(writerObj,im2frame(Frame));
end
close(writerObj);
It seems that there is a problem with the im2frame command. Guessing it doesn't work with tif files? Here's the error I'm getting.
Error using im2frame
Can only make movie frames from image matrices of type double or uint8
Error in test (line 71)
writeVideo(writerObj,im2frame(Frame))
Image Analyst
on 11 Sep 2013
Edited: Image Analyst
on 11 Sep 2013
What does "whos Frame" show? Isn't your image a 2D grayscale or color image of type uint8? For example, is it a 16 bit image? If so, divide by 256 and cast to uint8.
John
on 11 Sep 2013
Nevermind, it works now. It was the type of image I was trying to use. Thanks again for all your help.
John
on 30 Oct 2013
Have a question very similar to this post...
How would I take images in a folder and use them to create a PowerPoint presentation using MATLAB? I know how to recurse into the subfolders thanks to you, but instead of using the images to create a video, how would I use them to create a PP? Seems it wouldn't be much different from this.
Image Analyst
on 30 Oct 2013
You'd have to use ActiveX programming to control Powerpoint. Search the forum or MATLAB Central for ActiveX examples. I've attached one below, but it's for Word, not Powerpoint, but it will be similar though the methods will have different names of course.
John
on 26 Nov 2013
I sent you a private message through MathWorks needing help on something else, but you always replied quickly when posting to a topic (maybe my message didn't go through).
It was regarding how to measure the radius of curvature of a crater or dimple on a surface (rounded surface with an indention in it, need to measure the indention's radius of curvature).
Image Analyst
on 26 Nov 2013
Never saw a message. I don't get or use email for this account. Why don't you start a new discussion and post some images and your code?
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)