Reputation: 151
I'm trying to use the MPII Human Pose Dataset (found here) to train a neural network in Keras. By default, the datasets are in MATLAB format, but I loaded it into a Numpy array using scipy.io.loadmat
. However, I'm not able to make sense of the object that this produces - it seems to contain a single key called 'RELEASE'
and the annotations for the dataset as the value. My problem is that I can't figure out how to access the dataset and split it into annotations.
I'd really appreciate some help with this issue.
Upvotes: 1
Views: 1901
Reputation: 21
Inspired by bobxxxl's answer, I wrote a simple function to convert the object to dict format, and also a print_dataset_obj method to visualise it. Hope it helps.
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)
Upvotes: 2
Reputation: 41
The MPII data annotations.mat file is from matlab and it is a struct type in matlab, so if you want to process it using scipy.io.loadmat, you should add the argument like this:
matph = './mpii_human_pose_v1_u12_1.mat'
mat = sio.loadmat(matph, struct_as_record=False) # add here
let's print mat:
{'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__': []}
it is a dictionary so we get it's value:
release = mat['RELEASE']
let's print release's some attribute:
print(release, type(release), release.shape)
(array([[<scipy.io.matlab.mio5_params.mat_struct object at 0x7fd407de1790>]],
dtype=object), <type 'numpy.ndarray'>, (1, 1))
the release is a array whose element is a scipy.io.matlab.mio5_params.mat_struct object, here we can use the object's two method: __dict__
and _fieldnames
like this:
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))
we get a array contains 24987 elements which also scipy.io.matlab.mio5_params.mat_struct objects. then we can continue to research:
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))
Upvotes: 4