【问题标题】:python struct.pack and write vs matlab fwritepython struct.pack and write vs matlab fwrite
【发布时间】:2017-02-07 15:56:07
【问题描述】:

我正在尝试将这段 matlab 代码移植到 python

ma​​tlab

function write_file(im,name)
 fp = fopen(name,'wb');

 M = size(im);

 fwrite(fp,[M(1) M(2) M(3)],'int');
 fwrite(fp,im(:),'float');

 fclose(fp);

im 是一个 3D 矩阵。据我了解,该函数首先写入一个带有包含矩阵大小的标题行的二进制文件。标题由 3 个整数组成。然后,im 被写为单列浮点数。在 matlab 中,对于 150MB 的文件,这需要几秒钟。

蟒蛇

import struct
import numpy as np
def write_image(im, file_name):

    with open(file_name, 'wb') as f:
       l = im.shape[0]*im.shape[1]*im.shape[2]

       header = np.array([im.shape[0], im.shape[1], im.shape[2]])
       header_bin = struct.pack("I"*3, *header)
       f.write(header_bin)

       im_bin = struct.pack("f"*l,*np.reshape(im, (l,1), order='F'))
       f.write(im_bin)
    f.close()

im 是一个 numpy 数组。这段代码运行良好,因为我与 matlab 返回的二进制文件进行了比较,它们是相同的。然而,对于 150MB 的文件,它需要几秒钟并且往往会耗尽所有内存(在链接的图像中,我停止执行以避免它,但你可以看到它是如何建立的!)。

这对我来说没有意义,因为我在 15GB RAM 的 PC 上运行该功能。处理一个 150MB 的文件怎么需要这么大的内存?

我很乐意使用不同的方法,只要标题和数据列可以有两种格式。

【问题讨论】:

  • 不需要产品:l = im.size
  • 什么是header
  • 另外,是的,您创建了一个与整个图像大小相同的字符串,然后复制了整个图像本身。是的,那会把你吸干的。
  • 感谢您的更新。 np.array([im.shape[0], im.shape[1], im.shape[2]]) -> np.array(im.shape)
  • 固定,header 是一个数组,里面有im.shape

标签: python matlab numpy memory struct


【解决方案1】:

无需使用struct 来保存您的数组。 numpy.ndarray 有一个方便的方法以二进制模式保存自己:ndarray.tofile。以下应该比创建一个与数组具有相同数量元素的巨大字符串更有效:

def write_image(im, file_name):
    with open(file_name, 'wb') as f:
        np.array(im.shape).tofile(f)
        im.T.tofile(f)

tofile 始终以行优先的 C 顺序保存,而 MATLAB 使用列优先的 Fortran 顺序。解决这个问题的最简单方法是保存数组的转置。一般来说,ndarray.T 应该创建一个视图(指向相同底层数据的包装对象)而不是一个副本,因此您的内存使用量不会因该操作而显着增加。

【讨论】:

  • 绝对成功!谢谢我刚刚将最后一行修改为im.astype('f').T.tofile(f),以便数组在float32中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
  • 2015-06-27
  • 2020-09-18
  • 2012-08-07
相关资源
最近更新 更多