我正在尝试使用MPII人类姿势数据集(找到here)来训练Keras中的神经网络。默认情况下,数据集为MATLAB格式,但我使用scipy.io.loadmat
将其加载到Numpy数组中。但是,我无法理解由此产生的对象-它似乎包含一个名为'RELEASE'
的键,并且包含数据集的注释作为值。我的问题是我无法弄清楚如何访问数据集并将其拆分为注释。
我非常感谢您提供一些有关此问题的帮助。
答案 0 :(得分:1)
MPII数据注解.mat文件来自matlab,它是matlab中的结构类型,因此,如果要使用scipy.io.loadmat处理它,则应添加如下参数:
matph = './mpii_human_pose_v1_u12_1.mat'
mat = sio.loadmat(matph, struct_as_record=False) # add here
让我们的打印垫:
{'RELEASE': array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7f7b0ba51790>]],
dtype=object), '__version__': '1.0', '__header__': 'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Tue Sep 23 22:09:02 2014', '__globals__': []}
这是一本字典,所以我们得到它的价值:
release = mat['RELEASE']
让我们发布印刷品的某些属性:
print(release, type(release), release.shape)
(array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1790>]],
dtype=object), <type 'numpy.ndarray'>, (1, 1))
版本是一个数组,其元素是scipy.io.matlab.mio5_params.mat_struct对象,在这里我们可以使用该对象的两个方法:__dict__
和_fieldnames
,如下所示:
object1 = release[0,0]
print(object1._fieldnames)
['annolist', 'img_train', 'version', 'single_person', 'act', 'video_list']
annolist = object1.__dict__['annolist']
print(annolist, type(annolist), annolist.shape)
(array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1810>,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1850>,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1910>,
...,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd3db7f1710>,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd3db7f1c50>,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd3db794490>]],
dtype=object), <type 'numpy.ndarray'>, (1, 24987))
我们得到一个包含24987个元素的数组,这些元素也是scipy.io.matlab.mio5_params.mat_struct对象。 那么我们可以继续研究:
anno1 = annolist[0,0]
print(anno1._fieldnames)
['image', 'annorect', 'frame_sec', 'vididx']
annorect = anno1.__dict__['annorect']
print(annorect, type(annorect), annorect.shape)
(array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de19d0>,
<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1710>]],
dtype=object), <type 'numpy.ndarray'>, (1, 2))
anno2 = annorect[0,0]
print(anno2._fieldnames)
['scale', 'objpos']
objpos = anno2.__dict__['objpos']
print(objpos, type(objpos), objpos.shape)
(array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd398204b90>]],
dtype=object), <type 'numpy.ndarray'>, (1, 1))
objpos1 = objpos[0,0]
print(objpos1._fieldnames)
['x', 'y']
y = objpos1.__dict__['y']
print(y, type(y), y.shape)
(array([[210]], dtype=uint8), <type 'numpy.ndarray'>, (1, 1))
答案 1 :(得分:0)
受bobxxxl的回答启发,我编写了一个简单的函数将对象转换为dict格式,还编写了一个print_dataset_obj方法对其进行可视化。希望对您有所帮助。
decoded1 = scipy.io.loadmat(mat_path, struct_as_record=False)["RELEASE"]
must_be_list_fields = ["annolist", "annorect", "point", "img_train", "single_person", "act", "video_list"]
def generate_dataset_obj(obj):
if type(obj) == np.ndarray:
dim = obj.shape[0]
if dim == 1:
ret = generate_dataset_obj(obj[0])
else:
ret = []
for i in range(dim):
ret.append(generate_dataset_obj(obj[i]))
elif type(obj) == scipy.io.matlab.mio5_params.mat_struct:
ret = {}
for field_name in obj._fieldnames:
field = generate_dataset_obj(obj.__dict__[field_name])
if field_name in must_be_list_fields and type(field) != list:
field = [field]
ret[field_name] = field
else:
ret = obj
return ret
def print_dataset_obj(obj, depth = 0, maxIterInArray = 20):
prefix = " "*depth
if type(obj) == dict:
for key in obj.keys():
print("{}{}".format(prefix, key))
print_dataset_obj(obj[key], depth + 1)
elif type(obj) == list:
for i, value in enumerate(obj):
if i >= maxIterInArray:
break
print("{}{}".format(prefix, i))
print_dataset_obj(value, depth + 1)
else:
print("{}{}".format(prefix, obj))
# Convert to dict
dataset_obj = generate_dataset_obj(decoded1)
# Print it out
print_dataset_obj(dataset_obj)