How to create 4D array of images

60 views (last 30 days)
Ola Ola
Ola Ola on 20 Feb 2023
Commented: DGM on 26 Mar 2023
I have a group of images in a different folders such as folder A, B and C. Please how can I create a 4D array (like the inbuilt digitTrain4DArrayData) to hold these images in MATLAB?
  4 Comments
Jan
Jan on 21 Feb 2023
Edited: Jan on 21 Feb 2023
@Ola Ola: The images do not have file extensions? How can the list of images be defined? How can you decide, if an image should be included in the list or not? This decision has to be converted to code.
Do the images have the same size? If not, they do not match in a 4D array. You have to resize them before. The readers cannot guess, which properties to collection of images should have, so it is your turn to provide more details, e.g. the wanted size of the output.
DGM
DGM on 21 Feb 2023
Oh. I had read OP's response as "images do not have the same size" ... so I guess that question is still unclear.
Do the images have the same geometry (height and width)?
If not, what should the output geometry be?
  • the union of image geometries
  • the intersection of image geometries
  • some predetermined geometry
What is the preferred method of resolving geometry mismatch?
  • images should be padded to fit output
  • images should be cropped to fit output
  • images should be scaled to fill output, cropping any excess
  • images should be scaled to fit within output, padding any gaps
Do the images have the same color type or number of channels? i.e are they grayscale/logical/indexed/RGB
If not, what should the output have?
If there are other complications, describe them.
FWIW, I am not familiar with DLT, so I am blind do any conventions which you might think are being implied by the question.

Sign in to comment.

Answers (3)

KSSV
KSSV on 20 Feb 2023
Say you have n images each of size p,q.
data = zeros(p,q,1,n) ;
for i = 1:n
data(:,:,1,i) = image1 ; % loop for each image
end

DGM
DGM on 21 Feb 2023
Edited: DGM on 21 Feb 2023
I know there are many examples of batch reading and processing files. I'm not interested in repeating those. As I'm on my laptop and I don't have my list of reference answers, I'll leave it to you to do the forum search if you want.
Depending on the number of files and their size, this is how I would normally read a set of files of mismatched geometry/depth into a single 4D array. This example uses MIMT tools.
% build a path expression specifying the files you want
fprefix = fullfile(matlabroot,'toolbox','images','imdata')
fnames = {'c*.tif'};
% read the various files into a cell array
% any indexed images are converted to RGB
% verbose flag is optional, but might help with setup
instack = mimread(fprefix,fnames,'verbose');
% adapt the images to fit a common geometry
% images are padded with solid color (may be user-specified)
% output geometry is the union of page geometries (default)
% images are centered (default behavior)
% verbose flag is optional, but might help with setup
instack = imstacker(instack,'padding',[1 0.6 0.2], ...
'outclass','uint8','verbose');
% view the 4D image
imshow2('instack','tools') % view 4D array
This example should read five files from the IPT test image collection. Three of them are single-channel grayscale, one is single-channel logical, and one is indexed color. No two images share the same geometry.
MIMT mimread() will read various image types supported by imread(). Unlike imread(), indexed images are converted to RGB color, multiframe images are read in full as 4D images, JPG photographs with EXIF orientation are correctly oriented, and images with transparent content will be returned as IA/RGBA images. All images are stored in a cell array. When the 'verbose' flag is set, a list of the matched files and their sizes (height, width, channels, frames) are dumped to console.
MIMT imstacker() concatenates images of mismatched geometry. By default, images are concatenated on dim4, though dim1/2 concatenation are also supported. Output geometry and class can be specified. Image alignment and padding color can be specified. When the 'verbose' flag is set, a list of image sizes is displayed, as well as the calculated padding color, image offsets, and output image size and memory footprint. Note that imstacker() is greedy about array expansion, so if any of your images are RGB, the output will be RGB. If any of your images have transparent content, the output will have an alpha channel.
MIMT imshow2() extends on IPT imshow() to allow support of various features including the display of multiframe images and images with alpha. When the 'tools' flag is used, a new GUI is opened, allowing interactive browsing of the individual frames.
Are there disadvantages to using this workflow? Yes. This example requires third-party tools, so that's the obvious downside. This example also is likely to be slower and have higher peak memory usage than other methods. For example, one could get the list of files, use imfinfo() to get information about each file (color depth, page geometry, etc) in order to calculate the final image size. Then one could read and adjust each image to the final size one at a time. That would require less memory, but it would be a lot more complicated to write. The advantage of the example I gave is that it's simple to write and is usually sufficient for smallish, simple tasks.
That's just my take on it.
Is this example well-suited for your needs? Is using a 4D array the best way to do what you want? I don't know.
  5 Comments
Bartlomiej Mroczek
Bartlomiej Mroczek on 26 Mar 2023
It actually works, I use it myself.
And how to combine this data with time?
I would like to use the predict block from DL in SIMULINK and I have data and time on the input.
DGM
DGM on 26 Mar 2023
I do not know anything about DLT or how to use the Simulink blockset. I don't have DLT installed or a functioning installation of Simulink in any modern version.

Sign in to comment.


Jan
Jan on 21 Feb 2023
Maybe this is enough:
List = dir('C:\ParentOf_A_B_C', '**', '*.gif');
Array = [];
for k = 1:numel(List)
img = imread(fullfile(List(k).folder, List(k).name));
if isempty(Array)
Array = zeros([size(img), numel(List)]);
end
Array(:, :, :, k) = img;
end
But this is a cheap guessing only, because the question is not clear enough to define, which image files should be included.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!