Steve on Image Processing

June 6th, 2006

Batch processing

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

30 Responses to “Batch processing”

  1. shan replied on :

    hope you would kindly consider my problem and give me a solution for it.
    thank you

  2. zahid replied on :

    above program is not workin

  3. Steve replied on :

    zahid - Unless you provide a lot more detail about what problem you are having, I can’t possibly help you.

  4. Raja R replied on :

    its very useful to develop my self in image processing .

    thanking you sir.

    with warm regards
    R.Raja

  5. Lucy replied on :

    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

  6. Steve replied on :

    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.

  7. Lucy replied on :

    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?

  8. Steve replied on :

    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.

  9. Lucy replied on :

    Thanks Steve. Problem Solved!

  10. Manu replied on :

    Hi Steve,

    can I import a big number of MODIS images in HDF-EOS format whithout using HDF-toolbox?
    Thank in advance, Manu

  11. Steve replied on :

    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.

  12. Lakshman N replied on :

    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’);”.

  13. Steve replied on :

    Lakshman—I’m glad you found this information to be useful.

  14. Silver replied on :

    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

  15. Steve replied on :

    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.

  16. Pak replied on :

    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.

  17. Steve replied on :

    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.

  18. Pak replied on :

    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?

  19. Steve replied on :

    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.

  20. Pak replied on :

    Hi Steve,

    I just want to say thank you for your help!
    Have a good holiday!

  21. Ian replied on :

    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')
    end
    

    Subset that I tried as well, just to run the export function:

    files = dir('NEW*');
    for k = 1:numel(files)
        save(files(k).name,'-ASCII')
    end
    

    Not 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

  22. Steve replied on :

    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.

  23. Camilo replied on :

    Steve,

    Your code is working almost perfectly, but, whenever I go to the folder where I am storing the images I cannot see them. The files are there, but the images are blank. I am using Windows Picture and Fax viewer to open them. I can’t figure out if there is something with the code or there is something wrong with the Windows Picture and Fax viewer. This is the code I am using:

    close all
    files = dir (’D:\Users\Camilo\Matlab Programs\*.bmp’);

    for k = 1:numel(files)

    A = imread(files(k).name);
    % A = im2double(A);

    A2 = imcrop(A,[30 25 1152 928]);
    A3 = imcrop (A2,[539 165 1152 928]);

    [ypix,xpix] = size (A3);

    xdim = 1.98;
    ydim =(ypix/xpix)*xdim;
    xstart = -1;
    ystart =(892-904)*(xdim/xpix);
    x = 1.006;

    A3 = imagesc([xstart x],[ydim ystart], A3);

    grid on;
    axis image;
    axis xy;
    xlabel(’Axial Distance, in’)
    ylabel(’Vertical Distance, in’)
    colormap(gray);

    imwrite(A3, [’D:\Users\Camilo\Matlab Programs\Cropped\’files(k).name],’bmp’ )

    end

    Let me know what you think when you can. Thanks in advance.

    Camilo

  24. Camilo replied on :

    Steve !!!

    I changed imwrite for saveas and it worked !!!

    Thanks for showing us your code. It was very helpful.

    Camilo

  25. Steve replied on :

    Camilo—The function imwrite takes a matrix of pixel values. In your first attempt, you were passing it the handle of a MATLAB graphics object, and imwrite interpreted that as a single-pixel image.

  26. Sree replied on :

    I am a beginner and I am trying to read some file names in a directory and save it in an array variable.
    Can anyone help me?

  27. Steve replied on :

    Sree—The dir function returns a structure array containing the filenames and other information about the file.

    s = dir('*.jpg');
    

    You can combine the filenames into a single cell array using the comma-separated list syntax for structures:

    names = {s.name};
    
  28. Kaniska Mallick replied on :

    Hi Steve

    I am trying for batch processing using some satellite data whose names are as follows for example

    ID2r1-AMSRE-D.252004150A.v03.10V
    ID2r1-AMSRE-D.252004150A.v03.89V
    ID2r1-AMSRE-D.252004150D.v03.10V
    ID2r1-AMSRE-D.252004150D.v03.89V
    ID2r1-AMSRE-D.252004151A.v03.89V

    etc.

    these are the examples of files. I am unable to process them in batch. Although I could read them individually and then save them in mat format. But it takes time and I want to do batch processing and the necessary computations. May I ask your help?

  29. Steve replied on :

    Kaniska—Can you be more specific? Why are you unable to process the files in batch?

  30. Sana replied on :

    hi steve,

    could you explain to me how i would be able to use the dir function, to do a loop through a directory and all of the subfolders in the directory for files that have the following format.

    i have several subfolders in my directory. specifically ones that correspond to a date (ie. 20091011), and in each of those folders, there are several subfolders corresponding to a specific image set. In each of those folders are about 47 files, and I need to process the most recent/the last file in those folders

    I00000XX (XX = is a series of numbers corresponding to the file name)…. there is no file extension. (its a DICOM file).

    The subfolders are as follows:

    ImageData (contains 1 folder) > MDX1 (contains one folder) > image (contains several folders, each corresponding to a date) > 20091002 (contains several folders, each corresponding to a image set) > E0000012 > all of the files, of which the last file is the file I need.

    I want to create a list of sorts of all of these files (ie, path).

    Then I want to run an executable on all of these files, to get an output that i can save in matrix form

    thanks much!

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • Sana: hi steve, could you explain to me how i would be able to use the dir function, to do a loop through a directory...
  • Nishtha: Sir, I have preprocessed the image in following steps: [1] adaptive histogram equalization [2] thresholding...
  • Kristof: I also strongly support the idea. I have just recently bumped into the problem that im2single was not...
  • Steve: David—I’ m glad you found it useful!
  • David Lalejini: I found your example very useful for finding connected nodes in a large set of input pairs. I start...
  • tommy: Dear Steve, I have a question,please if you are kind to help me regarding the accumulator array dimensions of...
  • Steve: Abc—I don’t know how to distinguish the faces. You might try posting your question in the MATLAB...
  • Manju: well if we have a few ovals within each other like in a cell how do we measure the distance from the center...
  • Steve: Manju—What do you mean? How is each region defined?
  • Manju: if we have 2-3 regions within each other how do we measure the regions of each one?

These postings are the author's and don't necessarily represent the opinions of The MathWorks.