|
1 | 1 | # Customize Datasets |
2 | 2 |
|
3 | | -Coming soon. |
| 3 | +## Customize datasets by reorganizing data to COCO format |
| 4 | + |
| 5 | +The simplest way to use the custom dataset is to convert your annotation format to COCO dataset format. |
| 6 | + |
| 7 | +The annotation JSON files in COCO format have the following necessary keys: |
| 8 | + |
| 9 | +```python |
| 10 | +'images': [ |
| 11 | + { |
| 12 | + 'file_name': '000000001268.jpg', |
| 13 | + 'height': 427, |
| 14 | + 'width': 640, |
| 15 | + 'id': 1268 |
| 16 | + }, |
| 17 | + ... |
| 18 | +], |
| 19 | +'annotations': [ |
| 20 | + { |
| 21 | + 'segmentation': [[426.36, |
| 22 | + ... |
| 23 | + 424.34, |
| 24 | + 223.3]], |
| 25 | + 'keypoints': [0,0,0, |
| 26 | + 0,0,0, |
| 27 | + 0,0,0, |
| 28 | + 427,220,2, |
| 29 | + 443,222,2, |
| 30 | + 414,228,2, |
| 31 | + 449,232,2, |
| 32 | + 408,248,1, |
| 33 | + 454,261,2, |
| 34 | + 0,0,0, |
| 35 | + 0,0,0, |
| 36 | + 411,287,2, |
| 37 | + 431,287,2, |
| 38 | + 0,0,0, |
| 39 | + 458,265,2, |
| 40 | + 0,0,0, |
| 41 | + 466,300,1], |
| 42 | + 'num_keypoints': 10, |
| 43 | + 'area': 3894.5826, |
| 44 | + 'iscrowd': 0, |
| 45 | + 'image_id': 1268, |
| 46 | + 'bbox': [402.34, 205.02, 65.26, 88.45], |
| 47 | + 'category_id': 1, |
| 48 | + 'id': 215218 |
| 49 | + }, |
| 50 | + ... |
| 51 | +], |
| 52 | +'categories': [ |
| 53 | + {'id': 1, 'name': 'person'}, |
| 54 | + ] |
| 55 | +``` |
| 56 | + |
| 57 | +There are three necessary keys in the json file: |
| 58 | + |
| 59 | +- `images`: contains a list of images with their information like `file_name`, `height`, `width`, and `id`. |
| 60 | +- `annotations`: contains the list of instance annotations. |
| 61 | +- `categories`: contains the category name ('person') and its ID (1). |
| 62 | + |
| 63 | +If the annotations have been organized in COCO format, there is no need to create a new dataset class. You can use `CocoDataset` class alternatively. |
| 64 | + |
| 65 | +## Create a custom dataset_info config file for the dataset |
| 66 | + |
| 67 | +Add a new dataset info config file that contains the metainfo about the dataset. |
| 68 | + |
| 69 | +``` |
| 70 | +configs/_base_/datasets/custom.py |
| 71 | +``` |
| 72 | + |
| 73 | +An example of the dataset config is as follows. |
| 74 | + |
| 75 | +`keypoint_info` contains the information about each keypoint. |
| 76 | + |
| 77 | +1. `name`: the keypoint name. The keypoint name must be unique. |
| 78 | +2. `id`: the keypoint id. |
| 79 | +3. `color`: (\[B, G, R\]) is used for keypoint visualization. |
| 80 | +4. `type`: 'upper' or 'lower', will be used in data augmentation. |
| 81 | +5. `swap`: indicates the 'swap pair' (also known as 'flip pair'). When applying image horizontal flip, the left part will become the right part. We need to flip the keypoints accordingly. |
| 82 | + |
| 83 | +`skeleton_info` contains information about the keypoint connectivity, which is used for visualization. |
| 84 | + |
| 85 | +`joint_weights` assigns different loss weights to different keypoints. |
| 86 | + |
| 87 | +`sigmas` is used to calculate the OKS score. You can read [keypoints-eval](https://cocodataset.org/#keypoints-eval) to learn more about it. |
| 88 | + |
| 89 | +Here is an simplified example of dataset_info config file ([full text](/configs/_base_/datasets/coco.py)). |
| 90 | + |
| 91 | +``` |
| 92 | +dataset_info = dict( |
| 93 | + dataset_name='coco', |
| 94 | + paper_info=dict( |
| 95 | + author='Lin, Tsung-Yi and Maire, Michael and ' |
| 96 | + 'Belongie, Serge and Hays, James and ' |
| 97 | + 'Perona, Pietro and Ramanan, Deva and ' |
| 98 | + r'Doll{\'a}r, Piotr and Zitnick, C Lawrence', |
| 99 | + title='Microsoft coco: Common objects in context', |
| 100 | + container='European conference on computer vision', |
| 101 | + year='2014', |
| 102 | + homepage='http://cocodataset.org/', |
| 103 | + ), |
| 104 | + keypoint_info={ |
| 105 | + 0: |
| 106 | + dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''), |
| 107 | + 1: |
| 108 | + dict( |
| 109 | + name='left_eye', |
| 110 | + id=1, |
| 111 | + color=[51, 153, 255], |
| 112 | + type='upper', |
| 113 | + swap='right_eye'), |
| 114 | + ... |
| 115 | + 16: |
| 116 | + dict( |
| 117 | + name='right_ankle', |
| 118 | + id=16, |
| 119 | + color=[255, 128, 0], |
| 120 | + type='lower', |
| 121 | + swap='left_ankle') |
| 122 | + }, |
| 123 | + skeleton_info={ |
| 124 | + 0: |
| 125 | + dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]), |
| 126 | + ... |
| 127 | + 18: |
| 128 | + dict( |
| 129 | + link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]) |
| 130 | + }, |
| 131 | + joint_weights=[ |
| 132 | + 1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5, |
| 133 | + 1.5 |
| 134 | + ], |
| 135 | + sigmas=[ |
| 136 | + 0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062, |
| 137 | + 0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089 |
| 138 | + ]) |
| 139 | +``` |
| 140 | + |
| 141 | +## Create a custom dataset class |
| 142 | + |
| 143 | +If the annotations are not organized in COCO format, you need to create a custom dataset class by the following steps: |
| 144 | + |
| 145 | +1. First create a package inside the `mmpose/datasets/datasets` folder. |
| 146 | + |
| 147 | +2. Create a class definition of your dataset in the package folder and register it in the registry with a name. Without a name, it will keep giving the error. `KeyError: 'XXXXX is not in the dataset registry'` |
| 148 | + |
| 149 | + ``` |
| 150 | + from mmengine.dataset import BaseDataset |
| 151 | + from mmpose.registry import DATASETS |
| 152 | +
|
| 153 | + @DATASETS.register_module(name='MyCustomDataset') |
| 154 | + class MyCustomDataset(BaseDataset): |
| 155 | + ``` |
| 156 | + |
| 157 | + You can refer to [this doc](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html) on how to build customed dataset class with `mmengine.BaseDataset`. |
| 158 | + |
| 159 | +3. Make sure you have updated the `__init__.py` of your package folder |
| 160 | + |
| 161 | +4. Make sure you have updated the `__init__.py` of the dataset package folder. |
| 162 | + |
| 163 | +## Create a custom training config file |
| 164 | + |
| 165 | +Create a custom training config file as per your need and the model/architecture you want to use in the configs folder. You may modify an existing config file to use the new custom dataset. |
| 166 | + |
| 167 | +In `configs/my_custom_config.py`: |
| 168 | + |
| 169 | +```python |
| 170 | +... |
| 171 | +# dataset and dataloader settings |
| 172 | +dataset_type = 'MyCustomDataset' # or 'CocoDataset' |
| 173 | + |
| 174 | +train_dataloader = dict( |
| 175 | + batch_size=2, |
| 176 | + dataset=dict( |
| 177 | + type=dataset_type, |
| 178 | + data_root='root/of/your/train/data', |
| 179 | + ann_file='path/to/your/train/json', |
| 180 | + data_prefix=dict(img='path/to/your/train/img'), |
| 181 | + metainfo=dict(from_file='configs/_base_/datasets/custom.py'), |
| 182 | + ...), |
| 183 | + ) |
| 184 | + |
| 185 | +val_dataloader = dict( |
| 186 | + batch_size=2, |
| 187 | + dataset=dict( |
| 188 | + type=dataset_type, |
| 189 | + data_root='root/of/your/val/data', |
| 190 | + ann_file='path/to/your/val/json', |
| 191 | + data_prefix=dict(img='path/to/your/val/img'), |
| 192 | + metainfo=dict(from_file='configs/_base_/datasets/custom.py'), |
| 193 | + ...), |
| 194 | + ) |
| 195 | + |
| 196 | +test_dataloader = dict( |
| 197 | + batch_size=2, |
| 198 | + dataset=dict( |
| 199 | + type=dataset_type, |
| 200 | + data_root='root/of/your/test/data', |
| 201 | + ann_file='path/to/your/test/json', |
| 202 | + data_prefix=dict(img='path/to/your/test/img'), |
| 203 | + metainfo=dict(from_file='configs/_base_/datasets/custom.py'), |
| 204 | + ...), |
| 205 | + ) |
| 206 | +... |
| 207 | +``` |
| 208 | + |
| 209 | +Make sure you have provided all the paths correctly. |
| 210 | + |
| 211 | +## Dataset Wrappers |
| 212 | + |
| 213 | +The following dataset wrappers are supported in [MMEngine](https://github.com/open-mmlab/mmengine), you can refer to [MMEngine tutorial](https://mmengine.readthedocs.io/en/latest) to learn how to use it. |
| 214 | + |
| 215 | +- [ConcatDataset](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html#concatdataset) |
| 216 | +- [RepeatDataset](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html#repeatdataset) |
| 217 | + |
| 218 | +### CombinedDataset |
| 219 | + |
| 220 | +MMPose provides `CombinedDataset` to combine multiple datasets with different annotations. A combined dataset can be defined in config files as: |
| 221 | + |
| 222 | +```python |
| 223 | +dataset_1 = dict( |
| 224 | + type='dataset_type_1', |
| 225 | + data_root='root/of/your/dataset1', |
| 226 | + data_prefix=dict(img_path='path/to/your/img'), |
| 227 | + ann_file='annotations/train.json', |
| 228 | + pipeline=[ |
| 229 | + # the converter transforms convert data into a unified format |
| 230 | + converter_transform_1 |
| 231 | + ]) |
| 232 | + |
| 233 | +dataset_2 = dict( |
| 234 | + type='dataset_type_2', |
| 235 | + data_root='root/of/your/dataset2', |
| 236 | + data_prefix=dict(img_path='path/to/your/img'), |
| 237 | + ann_file='annotations/train.json', |
| 238 | + pipeline=[ |
| 239 | + converter_transform_2 |
| 240 | + ]) |
| 241 | + |
| 242 | +shared_pipeline = [ |
| 243 | + LoadImage(), |
| 244 | + ParseImage(), |
| 245 | +] |
| 246 | + |
| 247 | +combined_dataset = dict( |
| 248 | + type='CombinedDataset', |
| 249 | + metainfo=dict(from_file='path/to/your/metainfo'), |
| 250 | + datasets=[dataset_1, dataset_2], |
| 251 | + pipeline=shared_pipeline, |
| 252 | +) |
| 253 | +``` |
| 254 | + |
| 255 | +- **MetaInfo of combined dataset** determines the annotation format. Either metainfo of a sub-dataset or a customed dataset metainfo is valid here. To custom a dataset metainfo, please refer to [Create a custom dataset_info config file for the dataset](#create-a-custom-datasetinfo-config-file-for-the-dataset). |
| 256 | + |
| 257 | +- **Converter transforms of sub-datasets** are applied when there exist mismatches of annotation format between sub-datasets and the combined dataset. For example, the number and order of keypoints might be different in the combined dataset and the sub-datasets. Then `KeypointConverter` can be used to unify the keypoints number and order. |
| 258 | + |
| 259 | +- More details about `CombinedDataset` and `KeypointConverter` can be found in Advanced Guides-[Training with Mixed Datasets](../advanced_guides/mixed_datasets.md). |
0 commit comments