How to put these images together?
I have 200
time points. For each time point, there is an image, the size of which is 40*40 double
, corresponds to this time point. For example, image 1
corresponds to time point 1
; image k
corresponds to time point k
(k = 1,2,...,200
).
The time points are T = 1:200
, with the images named as Image_T
, thus Image_1
, Image_2
etc.
I want to put all these 200
images together. The final size is 40*40*200
double. The final image looks like fMRI image (fmri_szX = 40
, fmri_szY = 40
and fmri_szT = 200
). How to achieve that?
Thanks!
Dynamic variables
Note that whilst this is possible, it's considered to be bad programming (see for instance here, or this blog by Loren and even the Mathworks in their documentation tell you not to do this). It would be much better to load your images directly into either a 3D array or a cell structure, avoiding dynamic variable names. I just posted this for completeness; if you ever happen to have to use this solution, you should change to a (cell-) array immediately.
The gist of the linked articles as to why eval
is such a bad idea, is that MATLAB can no longer predict what the outcome of the operation will be. For instance A=3*(2:4)
is recognised by MATLAB to output a double-array. If you eval
stuff, MATLAB can no longer do this. MATLAB is an interpreted language, i.e. each line of code is read then ran, without compiling the entire code beforehand. This means that each time MATLAB encounters eval
, it has to stop, evaluate the expression, then check the output, store that, and continue. Most of the speed-engines employed by MATLAB (JIT/MAGMA etc) can't work without predicting the outcome of statements, and will therefore shut down during the eval
evaluation, rendering your code very slow.
Also there's a security aspect to the usage of eval
. Consider the following:
var1=1;
var2=2;
var3=3;
varnames={'var1','var2; disp(''GOTCHA''); %', 'var3'};
accumvar=[];
for k=1:numel(varnames)
vname=varnames{k};
disp(['Reading from variable named ' vname]); eval(['accumvar(end+1)=' vname ';']);
end
Now accumvar
will contain the desired variable names. But if you don't set accumvar
as output, you might as well not use a disp
, but e.g. eval('rm -rf ~/*')
which would format your entire disk without even telling you it's doing so.
Loop approach
for ii = 200:-1:1
str = sprintf('Image_%d',ii);
A(:,:,ii) = eval(str);
end
This creates your matrix. Note that I let the for
loop run backwards, so as to initialise A
in its largest size.
Semi-vectorised approach
str=strsplit(sprintf('image_%d ',1:200),' '); % Create all your names
str(end)=[]; % Delete the last entry (empty)
%Problem: eval cannot handle cells, loop anyway:
for ii = 200:-1:1
A(:,:,ii)=eval(str{ii});
end
eval
does not support arrays, so you cannot directly plug the cellarray str
in.
Dynamic file names
Despite having a similar title as above, this implies having your file names structured, so in the file browser, and not MATLAB. I'm assuming .jpg files here, but you can add every supported image extension. Also, be sure to have all images in a single folder and no additional images with that extension, or you have to modify the dir()
call to include only the desired images.
filenames = dir('*.jpg');
for ii = length(filenames):-1:1
A(:,:,:,ii) = imread(filenames{ii});
end
Images are usually read as m*n*3
files, where m*n
is your image size in pixels and the 3
stems from the fact that they're read as RGB by imread
. Therefore A
is now a 4D matrix, structured as m*n*3*T
, where the last index corresponds to the time of the image, and the first three are your image in RGB format.
Since you do not specify how you obtain your 40*40
double, I have left the 4D matrix. Could be you read them and then switch to using a uint16
interpretation of RGB, which is a single number, which would result in a m*n*1*T
variable, which you can reduce to a 3D variable by calling A = squeeze(A(:,:,1,:));