我试图了解在Matlab中存储相同大小的多个图像的最有效内存的方法。
我在这里写的所有内容都是基于我的小知识而且可能不准确。
到目前为止,我知道我们可以读取单元格数组,多维数组,结构图中的图像。
num_imgs = 100;
nrow = 512;
ncol = 512;
cellArray = cell(1,num_imgs);
cellArray(1,:) = {zeros(nrow,ncol,'logical')};
threeDArray = zeros(nrow,ncol,num_imgs,'logical');
structArray(1:num_imgs ) = struct('Image', zeros(nrow,ncol,'logical'));
卫生组织
Name Size Bytes Class Attributes
cellArray 1x100 26225600 cell
ncol 1x1 8 double
nrow 1x1 8 double
num_imgs 1x1 8 double
structArray 1x100 26225664 struct
threeDArray 512x512x100 26214400 logical
从这个threeDArray
更好,因为它不需要连续数组的任何指针。
然而,cellArray
是第二好的,因为它只需要8字节额外的每个数组的指针(即,多100 * 8字节)。
最后,根据每个字段的标记,结构需要更多一些,我想。
现在,
还有其他可能的方法吗?
哪种读取,写入以及影响代码性能的其他重要参数的内存效率最高?
我理解单元格有指针,因此cellArray
中的每个元素都不必连续存储在内存中,而threeDArray
需要连续的内存。
有人可以解释影响性能的这类因素吗?
答案 0 :(得分:3)
cellArray
是第二好的,因为它只需要每个8字节数组的指针(即多100 * 8字节)。
事实并非如此。每个数组都有一个"标题" (指定其类型,大小等的内存块)R2017a中的标头是104个字节(我认为它在最新版本中稍大一些)。单元格数组包含数组,因此您在测试中看到的差异与3D数组相同:
26225600 - 26214400 = 11200
是
100 * (104 + 8) = 11200
单元格数组是一个指针数组(每个8字节)到数组(104字节+无论数据是什么)。
对于一个相当大的数据块的图像,这112字节的开销可以忽略不计。其他考虑因素,例如访问速度,变得更加重要。
在MATLAB中,两个数组可以指向相同的数据。所以做一些像
这样的事情I = C{4};
不会在C{4}
创建数组的副本,而是数组I
引用它。但是如果你使用3D数组,那么:
I = A(:,:,4);
确实复制,因为I
无法引用另一个数组的子集,它必须引用整个数据。
因此,使用3D阵列,处理单个图像需要大量来回复制像素数据,这在单元阵列中是不必要的。
结构数组在这里不是一个相关的数据结构,它等同于单元格数组,除了索引更复杂(我不知道这是否会转换为运行时增加)。也就是说,S(4).Image
比C{4}
涉及更多。但是,如果要为每个图像存储其他信息,则结构数组可能很有用。
正如您所注意到的,struct数组仅比单元数组大64个字节。这会存储字段名称Image
。再一次,在担心这段记忆的时候并不值得。
以下是在MATLAB中处理数据的其他方法的简短摘要,这些方法对我来说都不合理:
自定义对象类型:这里你仍在处理下面的普通数组,所以这里没有优点或缺点。如果您想添加特定于图像的方法,但这些类型很不错,但不要改变处理内存的方式。他们似乎确实增加了一些时间开销。
使用tall arrays,适用于不适合内存的非常大的数据,但我不认为有人会考虑使用这样的数组进行图像分析。
使用memory-mapped files,对于加快文件访问速度非常有用,但在这种情况下无法提供帮助。
从MATLAB与Java或Python对话,让他们进行内存处理。但是你可以完全跳过MATLAB并转到不同的环境。
所以我真的认为处理多个图像的两个有意义的选项是单元格数组(或其他异构容器,如结构或自定义对象)或3D数组。我不会考虑其他任何事情。
总结:使用单元格数组。