首页 > 解决方案 > 在 Matlab 中存储多个固定大小和数据类型的图像的所有可能和内存有效的方法是什么?

问题描述

我试图了解在 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需要连续的内存。

有人可以详细解释这种影响性能的因素吗?

标签: arraysmatlabmemory-management

解决方案


cellArray次佳,因为它只需要每个额外 8 字节数组的指针(即多 100*8 字节)。

这不是真的。每个数组都有一个“标头”(一个指定其类型、大小等的内存块)。R2017a 中的标头为 104 字节(我认为在最新版本中会大一些)。单元格数组包含数组,因此您在 3D 数组的测试中看到的差异:

26225600 - 26214400 = 11200

100 * (104 + 8) = 11200

元胞数组是指向数组(104 字节 + 无论其数据是什么)的指针数组(每个 8 字节)。

对于一个相当大的数据块的图像,这 112 字节的开销可以忽略不计。其他考虑因素,例如访问速度,变得更加重要。

在 MATLAB 中,两个数组可以指向相同的数据。所以做类似的事情

I = C{4};

不会在 处创建数组的副本C{4},而是数组I引用它。但是如果你使用 3D 数组,那么:

I = A(:,:,4);

确实会复制,因为I不能引用另一个数组的子集,它必须引用整个东西。

因此,使用 3D 阵列处理单个图像需要大量来回复制像素数据,而这在单元阵列中是不必要的。

结构数组在这里不是相关的数据结构,它相当于单元数组,除了索引更复杂(我不知道这是否会转化为运行时间增加)。也就是说,S(4).Image比 更多参与C{4}。但是,如果您想为每个图像存储附加信息,结构数组可能会很有用。

如您所见,结构数组仅比元胞数组大 64 个字节。这存储了字段名称Image。同样,担心这么多内存并不值得。

以下是在 MATLAB 中处理数据的其他方法的简短摘要,我觉得这些方法都不合理:

  • 自定义对象类型:这里你仍然在处理下面的普通数组,所以这里没有优点或缺点。如果您想添加特定于图像的方法,这些类型很好,但不要更改内存的处理方式。他们似乎确实增加了一些时间开销。

  • 使用tall 数组,适用于不适合内存的非常大的数据,但我认为没有人会考虑使用这样的数组进行图像分析。

  • 使用内存映射文件,有助于加快文件访问,但在这种情况下并没有真正的帮助。

  • 从 MATLAB 与 Java 或 Python 对话,让它们进行内存处理。但是,您不妨完全跳过 MATLAB 并转到不同的环境。

所以我真的认为处理多个图像的两个有意义的选项是单元数组(或其他异构容器,如结构或自定义对象)或 3D 数组。我不会考虑其他任何事情。

总结:使用元胞数组。


推荐阅读