Leeds Sports Pose

This topic describes how to manage the Leeds Sports Pose Dataset, which is a dataset with Keypoints2D label(Fig. 2).

../_images/example-Keypoints2D.png

Fig. 2 The preview of an image with labels from “Leeds Sports Pose”.

Authorize a Client Instance

An accesskey is needed to authenticate identity when using TensorBay.

from tensorbay import GAS

ACCESS_KEY = "Accesskey-*****"
gas = GAS(ACCESS_KEY)

Create Dataset

gas.create_dataset("LeedsSportsPose")

Organize Dataset

It takes the following steps to organize the “Leeds Sports Pose” dataset by the Dataset instance.

Step 1: Write the Catalog

A catalog contains all label information of one dataset, which is typically stored in a json file.

 1{
 2    "KEYPOINTS2D": {
 3        "keypoints": [
 4            {
 5                "number": 14,
 6                "names": [
 7                    "Right ankle",
 8                    "Right knee",
 9                    "Right hip",
10                    "Left hip",
11                    "Left knee",
12                    "Left ankle",
13                    "Right wrist",
14                    "Right elbow",
15                    "Right shoulder",
16                    "Left shoulder",
17                    "Left elbow",
18                    "Left wrist",
19                    "Neck",
20                    "Head top"
21                ],
22                "skeleton": [
23                    [0, 1],
24                    [1, 2],
25                    [3, 4],
26                    [4, 5],
27                    [6, 7],
28                    [7, 8],
29                    [9, 10],
30                    [10, 11],
31                    [12, 13],
32                    [12, 2],
33                    [12, 3]
34                ],
35                "visible": "BINARY"
36            }
37        ]
38    }
39}

The only annotation type for “Leeds Sports Pose” is Keypoints2D.

Important

See catalog table for more catalogs with different label types.

Step 2: Write the Dataloader

A dataloader is needed to organize the dataset into a Dataset instance.

 1#!/usr/bin/env python3
 2#
 3# Copyright 2021 Graviti. Licensed under MIT License.
 4#
 5# pylint: disable=invalid-name
 6# pylint: disable=missing-module-docstring
 7
 8import os
 9
10from ...dataset import Data, Dataset
11from ...exception import ModuleImportError
12from ...geometry import Keypoint2D
13from ...label import LabeledKeypoints2D
14from .._utility import glob
15
16DATASET_NAME = "LeedsSportsPose"
17
18
19def LeedsSportsPose(path: str) -> Dataset:
20    """Dataloader of the `Leeds Sports Pose`_ dataset.
21
22    .. _Leeds Sports Pose: https://sam.johnson.io/research/lsp.html
23
24    The folder structure should be like::
25
26        <path>
27            joints.mat
28            images/
29                im0001.jpg
30                im0002.jpg
31                ...
32
33    Arguments:
34        path: The root directory of the dataset.
35
36    Raises:
37        ModuleImportError: When the module "scipy" can not be found.
38
39    Returns:
40        Loaded :class:`~tensorbay.dataset.dataset.Dataset` instance.
41
42    """
43    try:
44        from scipy.io import loadmat  # pylint: disable=import-outside-toplevel
45    except ModuleNotFoundError as error:
46        raise ModuleImportError(error.name) from error  # type: ignore[arg-type]
47
48    root_path = os.path.abspath(os.path.expanduser(path))
49
50    dataset = Dataset(DATASET_NAME)
51    dataset.load_catalog(os.path.join(os.path.dirname(__file__), "catalog.json"))
52    segment = dataset.create_segment()
53
54    mat = loadmat(os.path.join(root_path, "joints.mat"))
55
56    joints = mat["joints"].T
57    image_paths = glob(os.path.join(root_path, "images", "*.jpg"))
58    for image_path in image_paths:
59        data = Data(image_path)
60        data.label.keypoints2d = []
61        index = int(os.path.basename(image_path)[2:6]) - 1  # get image index from "im0001.jpg"
62
63        keypoints = LabeledKeypoints2D()
64        for keypoint in joints[index]:
65            keypoints.append(  # pylint: disable=no-member  # pylint issue #3131
66                Keypoint2D(keypoint[0], keypoint[1], int(not keypoint[2]))
67            )
68
69        data.label.keypoints2d.append(keypoints)
70        segment.append(data)
71    return dataset

See Keipoints2D annotation for more details.

Note

Since the Leeds Sports Pose dataloader above is already included in TensorBay, so it uses relative import. However, the regular import should be used when writing a new dataloader.

from tensorbay.dataset import Data, Dataset
from tensorbay.geometry import Keypoint2D
from tensorbay.label import LabeledKeypoints2D

There are already a number of dataloaders in TensorBay SDK provided by the community. Thus, instead of writing, importing an available dataloader is also feasible.

from tensorbay.opendataset import LeedsSportsPose

dataset = LeedsSportsPose("path/to/dataset/directory")

Note

Note that catalogs are automatically loaded in available dataloaders, users do not have to write them again.

Important

See dataloader table for dataloaders with different label types.

Visualize Dataset

Optionally, the organized dataset can be visualized by Pharos, which is a TensorBay SDK plug-in. This step can help users to check whether the dataset is correctly organized. Please see Visualization for more details.

Upload Dataset

The organized “BSTLD” dataset can be uploaded to TensorBay for sharing, reuse, etc.

dataset_client = gas.upload_dataset(dataset, jobs=8)
dataset_client.commit("initial commit")

Similar with Git, the commit step after uploading can record changes to the dataset as a version. If needed, do the modifications and commit again. Please see Version Control for more details.

Read Dataset

Now “Leeds Sports Pose” dataset can be read from TensorBay.

dataset = Dataset("LeedsSportsPose", gas)

In dataset “Leeds Sports Pose”, there is one default segment "" (empty string). Get it by passing the segment name.

segment = dataset[0]

In the default segment, there is a sequence of data, which can be obtained by index.

data = segment[0]

In each data, there is a sequence of Keypoints2D annotations, which can be obtained by index.

label_keypoints2d = data.label.keypoints2d[0]
x = data.label.keypoints2d[0][0].x
y = data.label.keypoints2d[0][0].y
v = data.label.keypoints2d[0][0].v

There is only one label type in “Leeds Sports Pose” dataset, which is keypoints2d. The information stored in x (y) is the x (y) coordinate of one keypoint of one keypoints list. The information stored in v is the visible status of one keypoint of one keypoints list. See Keypoints2D label format for more details.

Delete Dataset

gas.delete_dataset("LeedsSportsPose")