Ritvik Mandyam
Ritvik Mandyam

Reputation: 151

Training a Keras classifier on MPII Human Pose dataset

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

Answers (2)

Qi Zhang
Qi Zhang

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

bobxxxl
bobxxxl

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

Related Questions