imagematlabimage-processingpcaface-recognition

How do I read multiple images into an array in MATLAB?


I am currently working on a PCA face recognition project and I am wondering how do I read multiple images into a matrix and then resize them to say 50x50. Im aware that I need to use Imread and pass in the images, followed by using imresize. Would it be something like the following?

myFolder = 'C:\Users\X';
filePattern = fullfile(myFolder, '*.jpg');
jpegFiles = dir(filePattern);
for k = 1:length(jpegFiles)
baseFileName = jpegFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray50x50 = imread(fullFileName);
imageArray50x50New = imresize(imageArray50x50, [50 50]);
imshow(imageArray30x40New) 

Is this a good approach? how would I resize the images correctly?

Thanks in advance, Mark


Solution

  • From what I have dealt with, the only way to read in multiple images from file is to do it serially and through a for loop. What you have currently is indeed a good approach, but you need to determine how you want to store all of these images in MATLAB. The two easiest options would be to create a 3D matrix where each slice is a 50 x 50 image you read from file or a cell array where each cell is a 50 x 50 image.

    If you want to do the first option, you would do something like this:

    %// Your code
    myFolder = 'C:\Users\X';
    filePattern = fullfile(myFolder, '*.jpg');
    jpegFiles = dir(filePattern);
    
    %// New - 3D matrix to store images
    imageMatrix = uint8(zeros(50,50,numel(jpegFiles)));
    
    %// Your code
    for k = 1:length(jpegFiles)
        baseFileName = jpegFiles(k).name;
        fullFileName = fullfile(myFolder, baseFileName);
        fprintf(1, 'Now reading %s\n', fullFileName);
        imageArray50x50 = imread(fullFileName);
        imageArray50x50New = imresize(imageArray50x50, [50 50]);
      
        %// New
        imageMatrix(:,:,k) = imageArray50x50New;
    end
    

    To access the kth image, you would do:

    img = imageMatrix(:,:,k);
    

    The above code is assuming that all of your images are of type uint8. If this isn't the case where your images are of different types, a cell array approach would be preferred.... so that'd be the second approach. If this is the case, then do this instead:

    %// Your code
    myFolder = 'C:\Users\X';
    filePattern = fullfile(myFolder, '*.jpg');
    jpegFiles = dir(filePattern);
    
    %// New - 3D matrix to store images
    imageMatrix = cell(1,numel(jpegFiles));
    
    %// Your code
    for k = 1:length(jpegFiles)
        baseFileName = jpegFiles(k).name;
        fullFileName = fullfile(myFolder, baseFileName);
        fprintf(1, 'Now reading %s\n', fullFileName);
        imageArray50x50 = imread(fullFileName);
        imageArray50x50New = imresize(imageArray50x50, [50 50]);
      
        %// New
        imageMatrix{k} = imageArray50x50New;
    end
    

    To access the kth image, you would do:

    img = imageMatrix{k};
    

    However, if you are dealing with PCA, then what I suggest you do instead is create a 2D matrix where each row is the unrolled version of the image and you would have as many rows as you have images. Therefore, each row would be a 1 x 2500 vector of intensities. The reason why you'd want it like this is because if you were to use the pca function in MATLAB, each row is a data point while each column is a variable. Therefore, you would do this instead:

    %// Your code
    myFolder = 'C:\Users\X';
    filePattern = fullfile(myFolder, '*.jpg');
    jpegFiles = dir(filePattern);
    
    %// New - 3D matrix to store images
    imageMatrix = zeros(numel(jpegFiles), 2500);
    
    %// Your code
    for k = 1:length(jpegFiles)
        baseFileName = jpegFiles(k).name;
        fullFileName = fullfile(myFolder, baseFileName);
        fprintf(1, 'Now reading %s\n', fullFileName);
        imageArray50x50 = imread(fullFileName);
        imageArray50x50New = imresize(imageArray50x50, [50 50]);
      
        %// New
        imageMatrix(k,:) = double(imageArray50x50New(:).');
    end
    

    Therefore, each row would be an image represented as a single vector. This statement: imageArray50x50New(:).' first converts the 50 x 50 image into a column vector, then it is transposed so that it becomes a row vector. Also, take notice that I made the image matrix double precision. I did this because pca is best suited for floating-point data, and so when I transformed each image into a row vector, I've casted the data to double to facilitate this.