From: Pragya on
Hi,
I want to read 50 images from a folder and extract some specific features from each frames by applying an image processing algorithm and store the feature vector for a particular frame in an apt data structure. After that, I want to store all these feature vectors (equal to the number of frames) in a text file and then make corresponding graphs for each feature vector and store them in a folder also. All this has to be done automatically using loops. Write now I'm having to do it individually for each frame which is taking a lot of time. Would anyone please suggest a way to do this?

From: us on
"Pragya " <pragoel12(a)yahoo.com> wrote in message <hvi3bh$kjm$1(a)fred.mathworks.com>...
> Hi,
> I want to read 50 images from a folder and extract some specific features from each frames by applying an image processing algorithm and store the feature vector for a particular frame in an apt data structure. After that, I want to store all these feature vectors (equal to the number of frames) in a text file and then make corresponding graphs for each feature vector and store them in a folder also. All this has to be done automatically using loops. Write now I'm having to do it individually for each frame which is taking a lot of time. Would anyone please suggest a way to do this?
>

a hint:
- this process certainly can be automatized on many levels...

http://matlabwiki.mathworks.com/MATLAB_FAQ#How_can_I_process_a_sequence_of_files.3F

us
From: ImageAnalyst on
Pragya:
I don't really know what "Write now I'm having to do it individually
for each frame which is taking a lot of time." means. How exactly do
you expect to process these images if it's not one image at a time?
Also, what is "a lot of time"? How many images are you going to
process? How long is it taking? How long the the maximum you're
willing to allow for this? Perhaps your code is inefficient, like it
loops over every single pixel row-by-row and column-by-column, but we
can't tell unless you share your code.

Here's a demo where I pull out frames from a movie and make up a
feature vector that is the mean red, green, and blue value, plus the
mean "gray" value of the frame.

You could easily adapt it using the link us gave you to read images
from a disk folder instead. You could also compute different things,
other than the mean like I did, if you want to.

For what it's worth, here is my demo code that I mentioned above:
BE SURE TO FIX (JOIN) ANY LINE BREAKS INTRODUCED BY THE NEWSREADER.

% Demo macro to extract frames and get frame means from an avi movie
% and save individual frames to separate image files.
% Also computes the mean gray value of the color channels.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 14;

% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end

% Open the rhino.avi demo movie that ships with MATLAB.
movieFullFileName = 'C:\Program Files\MATLAB\R2010a\toolbox\images
\imdemos\rhinos.avi';
% Check to see that it exists.
if ~exist(movieFullFileName, 'file')
strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new
one, or cancel', movieFullFileName);
response = questdlg(strErrorMessage, 'File not found', 'OK - choose a
new movie.', 'Cancel', 'OK - choose a new movie.');
if strcmpi(response, 'OK - choose a new movie.')
[baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
if ~isequal(baseFileName, 0)
movieFullFileName = fullfile(folderName, baseFileName);
else
return;
end
else
return;
end
end
try
mov = aviread(movieFullFileName);
% movie(mov);
% Make a special output folder to hold all the separate movie frames
% as their own image files.
outputFolder = fullfile(cd, 'Rhino Movie');
if ~exist(outputFolder, 'dir')
mkdir(outputFolder);
end
% Determine how many frames there are.
numberOfFrames = size(mov, 2);
numberOfFramesWritten = 0;
% Prepare a figure to show the images in the upper half of the
screen.
figure;
screenSize = get(0, 'ScreenSize');
newWindowPosition = [1 screenSize(4)/2 - 70 screenSize(3)
screenSize(4)/2];
set(gcf, 'Position', newWindowPosition); % Maximize figure.
% set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.

% Ask user if they want to write the individual frames out to
disk.
promptMessage = sprintf('Do you want to save the individual frames
out to individual disk files?');
button = questdlg(promptMessage, 'Save individual frames?', 'Yes',
'No', 'Yes');
if strcmp(button, 'Yes')
writeToDisk = true;
else
writeToDisk = false;
end

% Loop through the movie, writing all frames out.
% Each frame will be in a separate file with unique name.
meanGrayLevels = zeros(numberOfFrames, 1);
meanRedLevels = zeros(numberOfFrames, 1);
meanGreenLevels = zeros(numberOfFrames, 1);
meanBlueLevels = zeros(numberOfFrames, 1);
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisFrame = mov(frame).cdata;

% Display it
hImage = subplot(1,2,1);
image(thisFrame);
axis square;
caption = sprintf('Frame %4d of %d.', frame, numberOfFrames);
title(caption, 'FontSize', fontSize);

% Construct an output image file name.
outputBaseFileName = sprintf('Frame %4.4d.png', frame);
outputFullFileName = fullfile(outputFolder, outputBaseFileName);

% Stamp the name and frame number onto the image.
% At this point it's just going into the overlay,
% not actually getting written into the pixel values.
text(5, 15, outputBaseFileName, 'FontSize', 20);
drawnow; % Force it to refresh the window.

% Write the image array to the output file, if requested.
if writeToDisk
% Extract the image with the text "burned into" it.
frameWithText = getframe(gca);
% frameWithText.cdata is the image with the text
% actually written into the pixel values.
% Write it out to disk.
imwrite(frameWithText.cdata, outputFullFileName, 'png');
end

% Calculate the mean gray level.
grayImage = rgb2gray(thisFrame);
meanGrayLevels(frame) = mean(grayImage(:));

% Calculate the mean R, G, and B levels.
meanRedLevels(frame) = mean(mean(thisFrame(:, :, 1)));
meanGreenLevels(frame) = mean(mean(thisFrame(:, :, 2)));
meanBlueLevels(frame) = mean(mean(thisFrame(:, :, 3)));

% Plot the mean gray levels.
hPlot = subplot(1,2,2);
hold off;
plot(meanGrayLevels, 'k-', 'LineWidth', 2);
hold on;
plot(meanRedLevels, 'r-');
plot(meanGreenLevels, 'g-');
plot(meanBlueLevels, 'b-');

% Put title back because plot() erases the existing title.
title('Mean Gray Levels', 'FontSize', fontSize);
if frame == 1
xlabel('Frame Number');
yLabel('Gray Level');
% Get size data later for preallocation if we read
% the movie back in from disk.
[rows columns numberOfColorChannels] = size(thisFrame);
end

% Update user with the progress. Display in the command
window.
if writeToDisk
progressIndication = sprintf('Wrote frame %4d of %d.', frame,
numberOfFrames);
else
progressIndication = sprintf('Processed frame %4d of %d.',
frame, numberOfFrames);
end
disp(progressIndication);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
end

% Alert user that we're done.
if writeToDisk
finishedMessage = sprintf('Done! It wrote %d frames to folder
\n"%s"', numberOfFramesWritten, outputFolder);
else
finishedMessage = sprintf('Done! It processed %d frames of
\n"%s"', numberOfFramesWritten, movieFullFileName);
end
disp(finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.

% Exit if they didn't write any individual frames out to disk.
if ~writeToDisk
return;
end

% Ask user if they want to read the individual frames from the
disk,
% that they just wrote out, back into a movie and display it.
promptMessage = sprintf('Do you want to recall the individual
frames\nback from disk into a movie?\n(This will take several
seconds.)');
button = questdlg(promptMessage, 'Recall Movie?', 'Yes', 'No',
'Yes');
if strcmp(button, 'No')
return;
end

% Read the frame back in, and convert them to a movie.
% I don't know of any way to preallocate recalledMovie.
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);
end
% 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!');

catch ME
% Some error happened if you get here.
stError = lasterror;
strErrorMessage = sprintf('Error extracting movie frames from:\n\n%s\n
\nError: %s\n\n)', movieFullFileName, stError.message);
msgboxw(strErrorMessage);
end

From: Pragya on
"Pragya " <pragoel12(a)yahoo.com> wrote in message <hvi3bh$kjm$1(a)fred.mathworks.com>...
> Hi,
> I want to read 50 images from a folder and extract some specific features from each frames by applying an image processing algorithm and store the feature vector for a particular frame in an apt data structure. After that, I want to store all these feature vectors (equal to the number of frames) in a text file and then make corresponding graphs for each feature vector and store them in a folder also. All this has to be done automatically using loops. Write now I'm having to do it individually for each frame which is taking a lot of time. Would anyone please suggest a way to do this?
>

Thanks for the hint. I have done that part of getting the pixel data for each file and manipulating it. How should I store the graph I plot using the feature vectors corresponding to each frame? For 10 frames 10 feature vectors will be found and 10 graphs have to be plotted and stored. How should I implement this?
From: Pragya on
ImageAnalyst <imageanalyst(a)mailinator.com> wrote in message <73039f35-4288-4281-a423-ffa3eba55ee9(a)r27g2000yqb.googlegroups.com>...
> Pragya:
> I don't really know what "Write now I'm having to do it individually
> for each frame which is taking a lot of time." means. How exactly do
> you expect to process these images if it's not one image at a time?
> Also, what is "a lot of time"? How many images are you going to
> process? How long is it taking? How long the the maximum you're
> willing to allow for this? Perhaps your code is inefficient, like it
> loops over every single pixel row-by-row and column-by-column, but we
> can't tell unless you share your code.
>
> Here's a demo where I pull out frames from a movie and make up a
> feature vector that is the mean red, green, and blue value, plus the
> mean "gray" value of the frame.
>
> You could easily adapt it using the link us gave you to read images
> from a disk folder instead. You could also compute different things,
> other than the mean like I did, if you want to.
>
> For what it's worth, here is my demo code that I mentioned above:
> BE SURE TO FIX (JOIN) ANY LINE BREAKS INTRODUCED BY THE NEWSREADER.
>
> % Demo macro to extract frames and get frame means from an avi movie
> % and save individual frames to separate image files.
> % Also computes the mean gray value of the color channels.
> clc; % Clear the command window.
> close all; % Close all figures (except those of imtool.)
> imtool close all; % Close all imtool figures.
> clear; % Erase all existing variables.
> workspace; % Make sure the workspace panel is showing.
> fontSize = 14;
>
> % Change the current folder to the folder of this m-file.
> if(~isdeployed)
> cd(fileparts(which(mfilename)));
> end
>
> % Open the rhino.avi demo movie that ships with MATLAB.
> movieFullFileName = 'C:\Program Files\MATLAB\R2010a\toolbox\images
> \imdemos\rhinos.avi';
> % Check to see that it exists.
> if ~exist(movieFullFileName, 'file')
> strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new
> one, or cancel', movieFullFileName);
> response = questdlg(strErrorMessage, 'File not found', 'OK - choose a
> new movie.', 'Cancel', 'OK - choose a new movie.');
> if strcmpi(response, 'OK - choose a new movie.')
> [baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
> if ~isequal(baseFileName, 0)
> movieFullFileName = fullfile(folderName, baseFileName);
> else
> return;
> end
> else
> return;
> end
> end
> try
> mov = aviread(movieFullFileName);
> % movie(mov);
> % Make a special output folder to hold all the separate movie frames
> % as their own image files.
> outputFolder = fullfile(cd, 'Rhino Movie');
> if ~exist(outputFolder, 'dir')
> mkdir(outputFolder);
> end
> % Determine how many frames there are.
> numberOfFrames = size(mov, 2);
> numberOfFramesWritten = 0;
> % Prepare a figure to show the images in the upper half of the
> screen.
> figure;
> screenSize = get(0, 'ScreenSize');
> newWindowPosition = [1 screenSize(4)/2 - 70 screenSize(3)
> screenSize(4)/2];
> set(gcf, 'Position', newWindowPosition); % Maximize figure.
> % set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
>
> % Ask user if they want to write the individual frames out to
> disk.
> promptMessage = sprintf('Do you want to save the individual frames
> out to individual disk files?');
> button = questdlg(promptMessage, 'Save individual frames?', 'Yes',
> 'No', 'Yes');
> if strcmp(button, 'Yes')
> writeToDisk = true;
> else
> writeToDisk = false;
> end
>
> % Loop through the movie, writing all frames out.
> % Each frame will be in a separate file with unique name.
> meanGrayLevels = zeros(numberOfFrames, 1);
> meanRedLevels = zeros(numberOfFrames, 1);
> meanGreenLevels = zeros(numberOfFrames, 1);
> meanBlueLevels = zeros(numberOfFrames, 1);
> for frame = 1 : numberOfFrames
> % Extract the frame from the movie structure.
> thisFrame = mov(frame).cdata;
>
> % Display it
> hImage = subplot(1,2,1);
> image(thisFrame);
> axis square;
> caption = sprintf('Frame %4d of %d.', frame, numberOfFrames);
> title(caption, 'FontSize', fontSize);
>
> % Construct an output image file name.
> outputBaseFileName = sprintf('Frame %4.4d.png', frame);
> outputFullFileName = fullfile(outputFolder, outputBaseFileName);
>
> % Stamp the name and frame number onto the image.
> % At this point it's just going into the overlay,
> % not actually getting written into the pixel values.
> text(5, 15, outputBaseFileName, 'FontSize', 20);
> drawnow; % Force it to refresh the window.
>
> % Write the image array to the output file, if requested.
> if writeToDisk
> % Extract the image with the text "burned into" it.
> frameWithText = getframe(gca);
> % frameWithText.cdata is the image with the text
> % actually written into the pixel values.
> % Write it out to disk.
> imwrite(frameWithText.cdata, outputFullFileName, 'png');
> end
>
> % Calculate the mean gray level.
> grayImage = rgb2gray(thisFrame);
> meanGrayLevels(frame) = mean(grayImage(:));
>
> % Calculate the mean R, G, and B levels.
> meanRedLevels(frame) = mean(mean(thisFrame(:, :, 1)));
> meanGreenLevels(frame) = mean(mean(thisFrame(:, :, 2)));
> meanBlueLevels(frame) = mean(mean(thisFrame(:, :, 3)));
>
> % Plot the mean gray levels.
> hPlot = subplot(1,2,2);
> hold off;
> plot(meanGrayLevels, 'k-', 'LineWidth', 2);
> hold on;
> plot(meanRedLevels, 'r-');
> plot(meanGreenLevels, 'g-');
> plot(meanBlueLevels, 'b-');
>
> % Put title back because plot() erases the existing title.
> title('Mean Gray Levels', 'FontSize', fontSize);
> if frame == 1
> xlabel('Frame Number');
> yLabel('Gray Level');
> % Get size data later for preallocation if we read
> % the movie back in from disk.
> [rows columns numberOfColorChannels] = size(thisFrame);
> end
>
> % Update user with the progress. Display in the command
> window.
> if writeToDisk
> progressIndication = sprintf('Wrote frame %4d of %d.', frame,
> numberOfFrames);
> else
> progressIndication = sprintf('Processed frame %4d of %d.',
> frame, numberOfFrames);
> end
> disp(progressIndication);
> % Increment frame count (should eventually = numberOfFrames
> % unless an error happens).
> numberOfFramesWritten = numberOfFramesWritten + 1;
> end
>
> % Alert user that we're done.
> if writeToDisk
> finishedMessage = sprintf('Done! It wrote %d frames to folder
> \n"%s"', numberOfFramesWritten, outputFolder);
> else
> finishedMessage = sprintf('Done! It processed %d frames of
> \n"%s"', numberOfFramesWritten, movieFullFileName);
> end
> disp(finishedMessage); % Write to command window.
> uiwait(msgbox(finishedMessage)); % Also pop up a message box.
>
> % Exit if they didn't write any individual frames out to disk.
> if ~writeToDisk
> return;
> end
>
> % Ask user if they want to read the individual frames from the
> disk,
> % that they just wrote out, back into a movie and display it.
> promptMessage = sprintf('Do you want to recall the individual
> frames\nback from disk into a movie?\n(This will take several
> seconds.)');
> button = questdlg(promptMessage, 'Recall Movie?', 'Yes', 'No',
> 'Yes');
> if strcmp(button, 'No')
> return;
> end
>
> % Read the frame back in, and convert them to a movie.
> % I don't know of any way to preallocate recalledMovie.
> 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);
> end
> % 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!');
>
> catch ME
> % Some error happened if you get here.
> stError = lasterror;
> strErrorMessage = sprintf('Error extracting movie frames from:\n\n%s\n
> \nError: %s\n\n)', movieFullFileName, stError.message);
> msgboxw(strErrorMessage);
> end

Well, 'having to do it individually for each frame' obviously means that the m file containing the image processing algorithm has to be run for each frame BY CHANGING THE FRAME NO. in the code manually. I was asking for a method to apply the algorithm to a set of frames WITHOUT MANUAL INTERVENTION. I haven't asked for a method to improve code efficiency and obviously 'a lot of time' means manually having to change the frame no. for each frame. I hope the question is clear now!Here's my code:

files=dir('*.png');
num_files=numel(files);
images=cell(1,num_files);
for p=1:num_files
images{p}=imread(files(p).name);
in=images{p};
%the image processing algorithm to be applied to each frame.
% toplot is a 13X2 array containing x ad y values to plot.
axis([0 320 0 240]);
hold on;
for z=1:13
plot(toplot(z,1),toplot(z,2),'r*');
end
a=[toplot(1,1) toplot(2,1) toplot(3,1)];
b=[toplot(1,2) toplot(2,2) toplot(3,2)];
plot(a,b,'-r');
c=[toplot(4,1) toplot(5,1)];
d=[toplot(4,2) toplot(5,2)];
plot(c,d,'-r');
e=[toplot(8,1) toplot(9,1)];
f=[toplot(8,2) toplot(9,2)];
plot(e,f,'-r');
g=[toplot(8,1) toplot(10,1) toplot(12,1)];
h=[toplot(8,2) toplot(10,2) toplot(12,2)];
plot(g,h,'-r');
i=[toplot(9,1) toplot(11,1) toplot(13,1)];
j=[toplot(9,2) toplot(11,2) toplot(13,2)];
plot(i,j,'-r');
k=[toplot(6,1) toplot(4,1)];
l=[toplot(6,2) toplot(4,2)];
plot(k,l,'-r');
m=[toplot(7,1) toplot(5,1)];
n=[toplot(7,2) toplot(5,2)];
plot(m,n,'-r');
hold off;
file_name=sprintf('plot%d.png',p);
saveas(gcf,file_name,'png');

How do I save the toplot array(which would be different for each frame) in a text file to use it for reference later? Also, how to compare pixel values between two frames and set pixel values of one frame equal to some other frame in the loop. For example, I find out the center of mass of one frame and then of another one. If the COM of the second one is above a threshhold, i set it's COM equal to the COM of the previous frame.
Thanks for your code:)