이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Use images to create video, script to read through hundreds of folders to do it
조회 수: 10 (최근 30일)
이전 댓글 표시
John
2013년 8월 20일
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
Jan
2013년 8월 26일
The brute clearing header "clear all, close all, clc" reduces the power of the debugger for no real benefit.
채택된 답변
Image Analyst
2013년 8월 20일
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
John
2013년 8월 21일
편집: John
2013년 8월 21일
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
2013년 8월 21일
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
2013년 8월 21일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 26일
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
2013년 8월 27일
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
2013년 8월 27일
편집: Image Analyst
2013년 8월 27일
Try using imresize before you add the image. If that works, please go ahead and mark this answer as Accepted.
John
2013년 8월 28일
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
2013년 8월 28일
In your loop near the end where you imread() and assign into Frame, after that line,
Frame = imresize(Frame, [1280, 960])
John
2013년 8월 28일
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
2013년 8월 28일
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
2013년 8월 28일
Yeah it helps to put it in the right place. Image Analyst and Walter, thanks for the help!
John
2013년 9월 11일
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
2013년 9월 11일
편집: Image Analyst
2013년 9월 11일
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
2013년 9월 11일
Nevermind, it works now. It was the type of image I was trying to use. Thanks again for all your help.
John
2013년 10월 30일
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
2013년 10월 30일
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
2013년 11월 26일
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
2013년 11월 26일
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?
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- 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)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)