A couple of months ago I was working with a bunch of pictures I had taken at home. I had about 40 of them, and I needed to crop and resize them all the same way. Naturally, I wrote a MATLAB script to do it.
This experience reminded me that customers sometimes ask "How do I use the Image Processing Toolbox to do batch processing of my images?" Really, though, this isn't a toolbox question; it's a MATLAB question. In other words, the basic MATLAB techniques for batch processing apply to any domain, not just image processing.
Contents
Step 1: Get a list of filenames
If you use the dir function with an output argument, you get back a structure array containing the filenames, as well as other information about each file.
Let's say I want to process all files ending in .jpg:
files = dir('*.jpg')files =
42x1 struct array with fields:
name
date
bytes
isdir
The files struct array has 42 elements, indicating that there are 42 files matching "*.jpg" in the current directory. Let's look at the details for a couple of these files.
files(1)
ans =
name: 'IMG_0175.jpg'
date: '12-Feb-2006 10:49:30'
bytes: 962477
isdir: 0
files(end)
ans =
name: 'IMG_0216.jpg'
date: '12-Feb-2006 11:09:10'
bytes: 1004842
isdir: 0
Step 2: Determine the processing steps to follow for each file
There are four basic steps to follow for each file:
1. Read in the data from the file.
2. Process the data.
3. Construct the output filename.
4. Write out the processed data.
Here's what my read and processing steps looked like:
rgb = imread('IMG_0175.jpg'); % or rgb = imread(files(1).name); rgb = rgb(1:1800, 520:2000, :); rgb = imresize(rgb, 0.2, 'bicubic');
You have many options to consider for constructing the output filename. In my case, I wanted to use the same name but in a subfolder:
output_name = ['cropped\' files(1).name] % Use fullfile instead if you want % multiplatform portability
output_name = cropped\IMG_0175.jpg
Here's another example of output name construction. You might use something like this if you want to change image formats.
input_name = files(1).name
input_name = IMG_0175.jpg
[path, name, extension] = fileparts(input_name)
path =
''
name =
IMG_0175
extension =
.jpg
output_name = fullfile(path, [name '.tif'])output_name = IMG_0175.tif
Step 3: Put everything together in a for loop
Here's my complete batch processing loop:
files = dir('*.JPG'); for k = 1:numel(files) rgb = imread(files(k).name); rgb = rgb(1:1800, 520:2000, :); rgb = imresize(rgb, 0.2, 'bicubic'); imwrite(rgb, ['cropped\' files(k).name]); end
Get
the MATLAB code
Published with MATLAB® 7.2



hope you would kindly consider my problem and give me a solution for it.
thank you
above program is not workin
zahid - Unless you provide a lot more detail about what problem you are having, I can’t possibly help you.
its very useful to develop my self in image processing .
thanking you sir.
with warm regards
R.Raja
Hi Steve
I am trying to run part of your for loop for batch processing a folder of 52 images. The only part I am interested in is the
reading a batch of images in. That is I want to extract area of an object as opposed to cropping. So I started with the beginning of your code
files = dir(’F:\EPD Validation Study\Lab Processing from Field Trip 221107\Boags A\greater than 2\4\Boags 4 Lab JPGS Cropped\*.jpg’)
for k = 1:numel(files)
rgb = imread(files(k).name)
end
but I receive an error message “??? Error using ==> imread at 315
File “R0010864.JPG” does not exist.”
R0010864.jpg is the first image file in the folder “Boags 4 Lab JPGS Cropped”.
I am not sure what I am doing wrong. These images are rgb and are large in size (2000 x 2000 pix)and are being stored on an external hard drive.
I would appreciate any helpful suggestions/solutions you might have.
Thanks
Lucy
Lucy—If you look at files(k).name, you’ll see that it doesn’t include the full path. You either need to modify files(k).name to prepend the full path, or add the image directory to the MATLAB path, or make that directory your working directory.
Thanks for your help Steve. I shifted my images into the current (working) directory and used the code listed below:
files = dir(’*.JPG’);
for k = 1:(numel(files));
rgb = imread(files(k).name)
end
and I received the following error message:
??? Error using ==> imagesci\private\readjpg
Too many input arguments.
Error in ==> imread at 389
[X, map] = feval(fmt_s.read, filename, extraArgs{:});
This appears to be a syntax error that may be associated with the wrong file format? (my image is class unit 8 it is not an indexed color map). But I also initially though that this loop would read all images into the workspace (at once) but I have since realized that this cannot be the case as there is only a single variable rgb. Therefore each image must be read in one at a time and once the algorithm is applied to the image (or any other functions in the for loop) it will move onto the next image file in the directory. Am I on the right page or have I misunderstood what this code is doing?
Lucy—I don’t see any problem with your code, except that you left off the semicolon on the imread line. That will cause the pixel values (all of them!) to display in the command window. I recommend that you use the debugger to help with your debugging problem. Single-step through the code, and in particular step into imread. Examine the input arguments to imread to make sure they are what you expect. And yes, your loop (once debugged) will read all the images into the same variable, one at a time. If that’s not what you want, consider using a cell array instead.
Thanks Steve. Problem Solved!
Hi Steve,
can I import a big number of MODIS images in HDF-EOS format whithout using HDF-toolbox?
Thank in advance, Manu
Manu—MATLAB supports HDF-EOS import and export via the functions hdfgd, hdfpt, hdfsw. I don’t know what you mean by “HDF Toolbox.” There’s no MathWorks product with that name.
Thanks so much Steve.You are simply the best.I knew the problem was simple but just did not know where to look for.I googled “matlab code to read all images in a folder” and got the best result.its quite surprising to see that the crux of this problem is just one line of code, namely, “files = dir(’*.JPG’);”.
Lakshman—I’m glad you found this information to be useful.
Hi Steve and everyone,
I came across Steve’s posting regarding batch processing.
However, I have tried the code you supplied but cannot go past the imread() statement.
Here is my practice code:
files = dir(’*.JPG’);
for k = 1:(numel(files));
image = imread(files(k).name);
newImage = imresize(image, 0.5);
imwrite(newImage, [’NewImage\’, files(k).name,]);
end
and this is the error I get:
??? Error using ==> imwrite
Can’t open file “NewImage\DSCF1639.JPG” for writing.
You may not have write permission.
Error in ==> firstProcessing at 14
imwrite(newImage, [’NewImage\’, files(k).name,])
??? Error using ==> imwrite
Can’t open file “NewImage\DSCF1639.JPG” for writing.
You may not have write permission.
Error in ==> firstProcessing at 14
imwrite(newImage, [’NewImage\’, files(k).name,])
What I want to attempt to do is to read over 200 images that are located in a folder called “Images”.
Then I want to resize the images and do image processing on each of these images. Then I want to store each image file in another folder called “ProcessedImages”. However, I want each image’s name to change to a new name, say image1.jpg.
Help in this regard will be very much appreciated.
Silver
Silver—From the error message, I’d guess that the folder called NewImage doesn’t exist before the call to imwrite. The error message says it all: “Can’t open file NewImage\foobar.jpg for writing. You may not have write permission.” That can happen because the folder doesn’t exist, or it does exist and you don’t have write permission to it, or you do have write permission to the folder but not to the file foobar.jpg that’s already in it.
hi steve,
I am trying to batch a sequence of images using the following code:
for k = 1:numel(files)
rgb = imread(files(k).name);
imwrite(rgb, [files(k).name], ‘png’);
end
I want to use the imwrite to save the output. At the same time, I want to save the file in png format instead of jpeg.
But I have trouble with assigning the index for imwrite.
Pak—You haven’t given me enough information to answer your question. What does happen when you run your code? An error message, unexpected behavior, or something else? Also, do you know that your code will just write over the original file with the same name, including the .jpg extension? You might want to look at the fileparts function so that you can construct a new filename with the appropriate extension.
Hi Steve,
There is no error message nor generating new file type. I guess my previous code wrote over the original files as you stated.
I tried this
imwrite(rgb,[’test’ files(k).name ‘.png’]);
It seems to work but the output file name is strange.
my output filename is like this:
testname0.jpeg.png
It is the file extension I wanted (that’s png) but how do I cancel the .jpeg?
Pak—The output file name you are getting is exactly what you instructed imwrite to do. In your code, you are concatenating ‘.png’ onto the end of the original file name. As I mentioned in my previous comment, I recommend that you use the fileparts function to help construct a new file name.
Hi Steve,
I just want to say thank you for your help!
Have a good holiday!
HI Steve,
I am new to MATLAB, and am trying to process some matrices, using the batch commands, roughly as you have outlined above. I have a number of .MAT files that were generated by a different program and I am trying to export the matrices (480×640 double) to individual ascii files. I am able to export a single file using
>save(’NEW0470′,’-ASCII). But have been unsuccessful to run this in a batch command format. I am also trying to change the file extension to .txt, Below are 2 examples of the scripts I have been trying to run, it seems that the renaming process is working well, but every time I try to run it, I get a warning message telling me
“Warning: Attempt to write an unsupported data type to an ASCII file.
Variable ‘files’ not written to file.
Entire scrip:
files = dir('NEW*'); for k = 1:numel(files) input_name = files(k).name [path, name, extension] = fileparts(input_name) output_name = fullfile(path, [name '.txt']) save(files(k).name,'-ASCII') endSubset that I tried as well, just to run the export function:
files = dir('NEW*'); for k = 1:numel(files) save(files(k).name,'-ASCII') endNot sure if this makes any sens to you, but if you have a chance to take a look and let me know what you think, would be fantastic.
Best regards,
Ian
Ian—When you use save with just the output filename and the -ascii option, it tries to save ALL the variables in the current workspace to the file. That’s almost certainly not what you intended. Also, the code that you included in your comment shows no call to load, so I have no where your script is getting the data you are trying to save. But generally, you’ll need to call load to read into a variable, and then supply the variable name in the call to save. Check the documentation for both load and save.