【问题标题】:how to read Mat v7.3 files in python ?如何在python中读取Mat v7.3文件?
【发布时间】:2016-02-04 04:45:39
【问题描述】:

我正在尝试读取以下网站 ufldl.stanford.edu/housenumbers 中给出的 mat 文件,在文件 train.tar.gz 中,有一个名为 digitStruct.mat 的 mat 文件。

当我使用 scipy.io 读取 mat 文件时,它会提醒我消息“请使用 hdf reader for matlab v7.3 files”。

原始matlab文件如下所示

load digitStruct.mat
for i = 1:length(digitStruct)
    im = imread([digitStruct(i).name]);
    for j = 1:length(digitStruct(i).bbox)
        [height, width] = size(im);
        aa = max(digitStruct(i).bbox(j).top+1,1);
        bb = min(digitStruct(i).bbox(j).top+digitStruct(i).bbox(j).height, height);
        cc = max(digitStruct(i).bbox(j).left+1,1);
        dd = min(digitStruct(i).bbox(j).left+digitStruct(i).bbox(j).width, width);

        imshow(im(aa:bb, cc:dd, :));
        fprintf('%d\n',digitStruct(i).bbox(j).label );
        pause;
    end
end

如上图,mat文件有key 'digitStruct',在'digitStruct'中可以找到key 'name'和'bbox',我使用h5py API读取文件。

import h5py
f = h5py.File('train.mat')
print len( f['digitStruct']['name'] ), len(f['digitStruct']['bbox']   )

我可以读取数组,但是当我循环遍历数组时,如何读取每个项目?

for i in f['digitStruct']['name']:
    print i # only print out the HDF5 ref

【问题讨论】:

  • 嘿,你有解决办法吗?我也有同样的问题。谢谢

标签: python matlab hdf5 mat h5py


【解决方案1】:

用 Matlab 编写:

test = {'Hello', 'world!'; 'Good', 'morning'; 'See', 'you!'};
save('data.mat', 'test', '-v7.3') % v7.3 so that it is readable by h5py

在 Python 中读取(适用于任何数字或行或列,但假定每个单元格都是一个字符串):

import h5py
import numpy as np

data = []
with h5py.File("data.mat") as f:
    for column in f['test']:
        row_data = []
        for row_number in range(len(column)):            
            row_data.append(''.join(map(unichr, f[column[row_number]][:])))   
        data.append(row_data)

print data
print np.transpose(data)

输出:

[[u'Hello', u'Good', u'See'], [u'world!', u'morning', u'you!']]

[[u'Hello' u'world!']
 [u'Good' u'morning']
 [u'See' u'you!']]

【讨论】:

    【解决方案2】:
    import numpy as np
    import cPickle as pickle
    import h5py
    
    f = h5py.File('train/digitStruct.mat')
    
    metadata= {}
    metadata['height'] = []
    metadata['label'] = []
    metadata['left'] = []
    metadata['top'] = []
    metadata['width'] = []
    
    def print_attrs(name, obj):
        vals = []
            if obj.shape[0] == 1:
                vals.append(int(obj[0][0]))
            else:
                for k in range(obj.shape[0]):
                    vals.append(int(f[obj[k][0]][0][0]))
            metadata[name].append(vals)
    
    for item in f['/digitStruct/bbox']:
        f[item[0]].visititems(print_attrs)
    
    with open('train_metadata.pickle','wb') as pf:
      pickle.dump(metadata, pf, pickle.HIGHEST_PROTOCOL)    
    

    我从https://discussions.udacity.com/t/how-to-deal-with-mat-files/160657/3 修改它。老实说,我无法弄清楚visititmes() 到底发生了什么。 HDF5 文件过于层次和抽象。

    这个元数据是一个字典。每个键的内容是一个嵌入式数组。该数组有 33402 个项,依次对应名称为 png 文件。每个项目都是一个长度为 1~6 的数组。我数了不同位数的个数,分别是 5137、18130、8691、1434、9,1。

    让我吃惊的是,pickle 文件只有 9 MB,比 mat 文件小 20 多倍。我猜HDS文件牺牲了层次结构的存储空间。

    注意:为了对图像进行切片,我已将这些值转换为整数。现在 train_metadata.pickle 文件的大小只有 2 MB,是 mat 文件的 100 倍。

    【讨论】:

      猜你喜欢
      • 2013-10-19
      • 2016-07-21
      • 2020-03-10
      • 2018-02-13
      • 2020-11-03
      • 2020-07-25
      相关资源
      最近更新 更多