How to put these images together?

前端 未结 1 925
鱼传尺愫
鱼传尺愫 2020-11-22 00:29

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,

1条回答
  •  情话喂你
    2020-11-22 01:00

    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 strin.

    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,:));

    0 讨论(0)
提交回复
热议问题