python读取复杂的Matlab struct mat文件

Pan*_* Li 5 python matlab scipy mat

我知道mat文件的版本问题,它们对应于python中的不同加载模块,即scipy.ioh5py。我还搜索了很多类似的问题,例如scipy.io.loadmat 嵌套结构(即字典)How to keep Matlab struct while accessing in python? 。但当涉及到更复杂的 mat 文件时,它们都会失败。我的anno_bbox.mat文件结构如下所示:

前两级:

anno_bbox

bbox_测试

尺寸方面:

尺寸

在海:

海

在海 bbox human 中:

bbox人

当我使用时spio.loadmat('anno_bbox.mat', struct_as_record=False, squeeze_me=True),它只能获取作为字典的第一级信息。

>>> anno_bbox.keys()
dict_keys(['__header__', '__version__', '__globals__', 'bbox_test', 
'bbox_train', 'list_action'])
>>> bbox_test = anno_bbox['bbox_test']
>>> bbox_test.keys()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute 'keys'
>>> bbox_test
array([<scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8660ab128>,
   <scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8660ab2b0>,
   <scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8660ab710>,
   ...,
   <scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8622ec4a8>,
   <scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8622ecb00>,
   <scipy.io.matlab.mio5_params.mat_struct object at 0x7fa8622f1198>], dtype=object)
Run Code Online (Sandbox Code Playgroud)

我不知道下一步该做什么。对我来说太复杂了。该文件位于anno_bbox.mat (8.7MB)

hpa*_*ulj 6

我得到(在这种情况下,使用共享文件是一个好主意):

加载:

data = io.loadmat('../Downloads/anno_bbox.mat')
Run Code Online (Sandbox Code Playgroud)

我得到:

In [96]: data['bbox_test'].dtype
Out[96]: dtype([('filename', 'O'), ('size', 'O'), ('hoi', 'O')])
In [97]: data['bbox_test'].shape
Out[97]: (1, 9658)
Run Code Online (Sandbox Code Playgroud)

我本来可以分配的bbox_test=data['bbox_test']。该变量有 9658 条记录,具有三个字段,每个字段都有对象数据类型。

所以有一个文件名(嵌入 1 元素数组中的字符串)

In [101]: data['bbox_test'][0,0]['filename']
Out[101]: array(['HICO_test2015_00000001.jpg'], dtype='<U26')
Run Code Online (Sandbox Code Playgroud)

size有 3 个字段,其中 3 个数字嵌入数组(2d matlab 矩阵):

In [102]: data['bbox_test'][0,0]['size']
Out[102]: 
array([[(array([[640]], dtype=uint16), array([[427]], dtype=uint16), array([[3]], dtype=uint8))]],
      dtype=[('width', 'O'), ('height', 'O'), ('depth', 'O')])
In [112]: data['bbox_test'][0,0]['size'][0,0].item()
Out[112]: 
(array([[640]], dtype=uint16),
 array([[427]], dtype=uint16),
 array([[3]], dtype=uint8))
Run Code Online (Sandbox Code Playgroud)

hoi更复杂的是:

In [103]: data['bbox_test'][0,0]['hoi']
Out[103]: 
array([[(array([[246]], dtype=uint8), array([[(array([[320]], dtype=uint16), array([[359]], dtype=uint16), array([[306]], dtype=uint16), array([[349]], dtype=uint16)),...
      dtype=[('id', 'O'), ('bboxhuman', 'O'), ('bboxobject', 'O'), ('connection', 'O'), ('invis', 'O')])


In [126]: data['bbox_test'][0,1]['hoi']['id']
Out[126]: 
array([[array([[132]], dtype=uint8), array([[140]], dtype=uint8),
        array([[144]], dtype=uint8)]], dtype=object)
In [130]: data['bbox_test'][0,1]['hoi']['bboxhuman'][0,0]
Out[130]: 
array([[(array([[226]], dtype=uint8), array([[340]], dtype=uint16), array([[18]], dtype=uint8), array([[210]], dtype=uint8))]],
      dtype=[('x1', 'O'), ('x2', 'O'), ('y1', 'O'), ('y2', 'O')])
Run Code Online (Sandbox Code Playgroud)

因此,您在 MATLAB 结构中显示的数据都在数组(通常是 2d (1,1) 形状)、对象数据类型或多个字段的嵌套结构中。

返回并加载squeeze_me我得到一个更简单的:

In [133]: data['bbox_test'][1]['hoi']['bboxhuman']
Out[133]: 
array([array((226, 340, 18, 210),
      dtype=[('x1', 'O'), ('x2', 'O'), ('y1', 'O'), ('y2', 'O')]),
       array((230, 356, 19, 212),
      dtype=[('x1', 'O'), ('x2', 'O'), ('y1', 'O'), ('y2', 'O')]),
       array((234, 342, 13, 202),
      dtype=[('x1', 'O'), ('x2', 'O'), ('y1', 'O'), ('y2', 'O')])],
      dtype=object)
Run Code Online (Sandbox Code Playgroud)

有了struct_as_record='False',我得到

In [136]: data['bbox_test'][1]
Out[136]: <scipy.io.matlab.mio5_params.mat_struct at 0x7f90841e9748>
Run Code Online (Sandbox Code Playgroud)

看看这个属性,rec我发现我可以通过属性名称访问“字段”:

In [137]: rec = data['bbox_test'][1]
In [138]: rec.filename
Out[138]: 'HICO_test2015_00000002.jpg'
In [139]: rec.size
Out[139]: <scipy.io.matlab.mio5_params.mat_struct at 0x7f90841e9b38>

In [141]: rec.size.width
Out[141]: 640
In [142]: rec.hoi
Out[142]: 
array([<scipy.io.matlab.mio5_params.mat_struct object at 0x7f90841e9be0>,
       <scipy.io.matlab.mio5_params.mat_struct object at 0x7f90841e9e10>,
       <scipy.io.matlab.mio5_params.mat_struct object at 0x7f90841ee0b8>],
      dtype=object)

In [145]: rec.hoi[1].bboxhuman
Out[145]: <scipy.io.matlab.mio5_params.mat_struct at 0x7f90841e9f98>
In [146]: rec.hoi[1].bboxhuman.x1
Out[146]: 230

In [147]: vars(rec.hoi[1].bboxhuman)
Out[147]: 
{'_fieldnames': ['x1', 'x2', 'y1', 'y2'],
 'x1': 230,
 'x2': 356,
 'y1': 19,
 'y2': 212}
Run Code Online (Sandbox Code Playgroud)

等等。