如何将这些图像放在一起?

时间:2015-09-08 20:51:49

标签: image matlab image-processing matlab-guide

我有200个时间点。对于每个时间点,有一个图像,其大小为40*40 double,对应于此时间点。例如,image 1对应time point 1; image k对应time point kk = 1,2,...,200)。

时间点为T = 1:200,图片名称为Image_T,因此Image_1Image_2等。

我想将所有这些200图像放在一起。最终大小为40*40*200两倍。最终图像看起来像fMRI图像(fmri_szX = 40fmri_szY = 40fmri_szT = 200)。怎么实现呢? 谢谢!

1 个答案:

答案 0 :(得分:16)

动态变量

请注意,虽然这是可能的,但它被认为是错误的编程(例如参见herethis blog by Loren,甚至是documentation中的Mathworks告诉你不要这样做)。将图像直接加载到3D数组或单元结构中会更好,避免使用动态变量名称。我刚刚发布了这个完整性;如果您碰巧必须使用此解决方案,则应立即更改为(cell-)数组。

关于为什么eval这么糟糕的想法的链接文章的要点是,MATLAB无法再预测操作的结果。例如,MATLAB识别A=3*(2:4)以输出双数组。如果你eval的东西,MATLAB就不能再做了。 MATLAB是一种解释型语言,即读取每行代码然后运行,而不事先编译整个代码。这意味着每次MATLAB遇到eval时,都必须停止,评估表达式,然后检查输出,存储并继续。 MATLAB(JIT / MAGMA等)使用的大多数速度引擎在没有预测语句结果的情况下无法工作,因此会在eval评估期间关闭,导致代码变慢。

eval的使用还有一个安全方面。请考虑以下事项:

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

现在accumvar将包含所需的变量名称。但是,如果您未将accumvar设置为输出,则不妨使用disp,例如eval('rm -rf ~/*')它会格式化整个磁盘,甚至不会告诉你它正在这样做。

循环方法

for ii = 200:-1:1
    str = sprintf('Image_%d',ii);
    A(:,:,ii) = eval(str);
end

这会创建您的矩阵。请注意,我让for循环向后运行,以便以最大的大小初始化A

半矢量化方法

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不支持数组,因此您无法直接插入cellarray str

动态文件名

尽管有类似的标题,但这意味着你的文件名是结构化的,所以在文件浏览器中,而不是MATLAB。我在这里假设.jpg文件,但您可以添加每个支持的图像扩展名。此外,请务必在单个文件夹中包含所有图像,并且不得使用该扩展程序添加其他图像,或者您必须修改dir()调用以仅包含所需图像。

filenames = dir('*.jpg');
for ii = length(filenames):-1:1
    A(:,:,:,ii) = imread(filenames{ii});
end

图片通常被视为m*n*3个文件,其中m*n是您的图片大小(以像素为单位),而3源于他们被{{1}读取为RGB的事实}。因此,imread现在是一个4D矩阵,结构为A,其中最后一个索引对应于图像的时间,前三个是RGB格式的图像。

由于您未指定获取m*n*3*T双精度的方式,我已经离开了4D矩阵。你可以阅读它们,然后切换到使用RGB的40*40解释,这是一个单一的数字,这将导致uint16变量,你可以通过调用{{{{}}变量将其变为3D变量1}}