我正在尝试阅读以下网站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文件的键为'digitStruct',在'digitStruct'中,可以找到键'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
答案 0 :(得分:4)
用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!']]
答案 1 :(得分:1)
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倍。