代码之家  ›  专栏  ›  技术社区  ›  Gopi

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

  •  2
  • Gopi  · 技术社区  · 6 年前

    我试图了解在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字节以上)提供指针。

    最后,我认为,结构需要更多一些,具体取决于每个字段的标记。

    现在

    有没有其他可能的方法来做到这一点。

    对于读、写和任何其他影响代码性能的重要参数,哪种方式是内存效率最高的?

    我知道单元格有指针,所以 酒窖射线 不必连续存储在内存中 三达雷 需要连续内存。

    有人能详细解释一下这种影响绩效的因素吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Cris Luengo    6 年前

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

    复制是因为 无法引用另一个数组的子集,它必须引用整个数组。

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

    结构数组在这里不是一个相关的数据结构,它将等同于单元数组,只是索引更复杂(我不知道这是否转化为运行时增加)。也就是说, S(4).Image C{4} 。但是,如果要为每个图像存储其他信息,结构数组可能会很有用。

    正如您所注意到的,struct数组只比cell数组大64字节。这将存储字段名 Image .再说一次,担心这么大的内存是不值得的。

    以下是在MATLAB中处理数据的其他方法的简短总结,我认为这些方法都不合理:

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

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

    • 使用 memory-mapped files ,有助于加快文件访问速度,但在这种情况下没有真正的帮助。

    • 与MATLAB中的Java或Python对话,并让他们进行内存处理。但是,您也可以完全跳过MATLAB,转到另一个环境。

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

    总而言之: 使用单元格数组。