2015-11-03 1 views
4

Я пытаюсь прочитать файл мата, указанный на следующем веб-сайте ufldl.stanford.edu/housenumbers, в файле train.tar.gz, есть файл мата named digitStruct.mat.Как читать файлы Mat v7.3 в python?

, когда я использовал scipy.io, чтобы прочитать файл мата, он предупреждает меня с сообщением «пожалуйста, используйте hdf-ридер для файлов Matlab v7.3».

исходный файл 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 

, как показано выше, файл мат имеет ключ «digitStruct», и в «digitStruct», ключ «имя» и «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 

enter image description here

Чтение в 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
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 МБ, что более чем в 20 раз меньше, чем файл мата. Я полагаю, что жертва HDS-файла хранит пространство для иерархической структуры.

Примечание: Я преобразовал значения в целые числа, чтобы нарезать изображения. Теперь файл train_metadata.pickle имеет размер всего 2 МБ, что в 100 раз больше, чем файл мата.