From 96ec68137100e442c504ff8cfa5aac5a33d244aa Mon Sep 17 00:00:00 2001 From: jinsheng Date: Tue, 18 Aug 2020 20:40:54 +0800 Subject: [PATCH 01/25] chmod -x --- configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py | 0 configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py | 0 configs/top_down/alexnet/coco/alexnet_coco_256x192.py | 0 configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py | 0 configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py | 0 configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py | 0 configs/top_down/darkpose/coco/res50_coco_256x192_dark.py | 0 configs/top_down/darkpose/coco/res50_coco_384x288_dark.py | 0 configs/top_down/hourglass/coco/hourglass52_coco_256x256.py | 0 configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py | 0 configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py | 0 configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py | 0 configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py | 0 configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py | 0 configs/top_down/resnet/coco/res101_coco_256x192.py | 0 configs/top_down/resnet/coco/res101_coco_384x288.py | 0 configs/top_down/resnet/coco/res152_coco_256x192.py | 0 configs/top_down/resnet/coco/res152_coco_384x288.py | 0 configs/top_down/resnet/coco/res50_coco_384x288.py | 0 configs/top_down/resnet/ochuman/res101_ochuman_256x192.py | 0 configs/top_down/resnet/ochuman/res101_ochuman_384x288.py | 0 configs/top_down/resnet/ochuman/res152_ochuman_256x192.py | 0 configs/top_down/resnet/ochuman/res152_ochuman_384x288.py | 0 configs/top_down/resnet/ochuman/res50_ochuman_384x288.py | 0 configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py | 0 configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py | 0 configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py | 0 configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py | 0 configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py | 0 configs/top_down/resnext/coco/resnext101_coco_256x192.py | 0 configs/top_down/resnext/coco/resnext101_coco_384x288.py | 0 configs/top_down/resnext/coco/resnext152_coco_256x192.py | 0 configs/top_down/resnext/coco/resnext152_coco_384x288.py | 0 configs/top_down/resnext/coco/resnext50_coco_384x288.py | 0 configs/top_down/scnet/coco/scnet101_coco_256x192.py | 0 configs/top_down/scnet/coco/scnet101_coco_384x288.py | 0 configs/top_down/scnet/coco/scnet50_coco_256x192.py | 0 configs/top_down/scnet/coco/scnet50_coco_384x288.py | 0 configs/top_down/seresnet/coco/seresnet101_coco_256x192.py | 0 configs/top_down/seresnet/coco/seresnet101_coco_384x288.py | 0 configs/top_down/seresnet/coco/seresnet152_coco_256x192.py | 0 configs/top_down/seresnet/coco/seresnet152_coco_384x288.py | 0 configs/top_down/seresnet/coco/seresnet50_coco_384x288.py | 0 configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py | 0 configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py | 0 45 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py mode change 100755 => 100644 configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py mode change 100755 => 100644 configs/top_down/alexnet/coco/alexnet_coco_256x192.py mode change 100755 => 100644 configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py mode change 100755 => 100644 configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py mode change 100755 => 100644 configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py mode change 100755 => 100644 configs/top_down/darkpose/coco/res50_coco_256x192_dark.py mode change 100755 => 100644 configs/top_down/darkpose/coco/res50_coco_384x288_dark.py mode change 100755 => 100644 configs/top_down/hourglass/coco/hourglass52_coco_256x256.py mode change 100755 => 100644 configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py mode change 100755 => 100644 configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py mode change 100755 => 100644 configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py mode change 100755 => 100644 configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py mode change 100755 => 100644 configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnet/coco/res101_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnet/coco/res101_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnet/coco/res152_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnet/coco/res152_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnet/coco/res50_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnet/ochuman/res101_ochuman_256x192.py mode change 100755 => 100644 configs/top_down/resnet/ochuman/res101_ochuman_384x288.py mode change 100755 => 100644 configs/top_down/resnet/ochuman/res152_ochuman_256x192.py mode change 100755 => 100644 configs/top_down/resnet/ochuman/res152_ochuman_384x288.py mode change 100755 => 100644 configs/top_down/resnet/ochuman/res50_ochuman_384x288.py mode change 100755 => 100644 configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnext/coco/resnext101_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnext/coco/resnext101_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnext/coco/resnext152_coco_256x192.py mode change 100755 => 100644 configs/top_down/resnext/coco/resnext152_coco_384x288.py mode change 100755 => 100644 configs/top_down/resnext/coco/resnext50_coco_384x288.py mode change 100755 => 100644 configs/top_down/scnet/coco/scnet101_coco_256x192.py mode change 100755 => 100644 configs/top_down/scnet/coco/scnet101_coco_384x288.py mode change 100755 => 100644 configs/top_down/scnet/coco/scnet50_coco_256x192.py mode change 100755 => 100644 configs/top_down/scnet/coco/scnet50_coco_384x288.py mode change 100755 => 100644 configs/top_down/seresnet/coco/seresnet101_coco_256x192.py mode change 100755 => 100644 configs/top_down/seresnet/coco/seresnet101_coco_384x288.py mode change 100755 => 100644 configs/top_down/seresnet/coco/seresnet152_coco_256x192.py mode change 100755 => 100644 configs/top_down/seresnet/coco/seresnet152_coco_384x288.py mode change 100755 => 100644 configs/top_down/seresnet/coco/seresnet50_coco_384x288.py mode change 100755 => 100644 configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py mode change 100755 => 100644 configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py diff --git a/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py b/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py old mode 100755 new mode 100644 diff --git a/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py b/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py old mode 100755 new mode 100644 diff --git a/configs/top_down/alexnet/coco/alexnet_coco_256x192.py b/configs/top_down/alexnet/coco/alexnet_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py b/configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py old mode 100755 new mode 100644 diff --git a/configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py b/configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py old mode 100755 new mode 100644 diff --git a/configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py b/configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py old mode 100755 new mode 100644 diff --git a/configs/top_down/darkpose/coco/res50_coco_256x192_dark.py b/configs/top_down/darkpose/coco/res50_coco_256x192_dark.py old mode 100755 new mode 100644 diff --git a/configs/top_down/darkpose/coco/res50_coco_384x288_dark.py b/configs/top_down/darkpose/coco/res50_coco_384x288_dark.py old mode 100755 new mode 100644 diff --git a/configs/top_down/hourglass/coco/hourglass52_coco_256x256.py b/configs/top_down/hourglass/coco/hourglass52_coco_256x256.py old mode 100755 new mode 100644 diff --git a/configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py b/configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py b/configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py b/configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py b/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py b/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/coco/res101_coco_256x192.py b/configs/top_down/resnet/coco/res101_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/coco/res101_coco_384x288.py b/configs/top_down/resnet/coco/res101_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/coco/res152_coco_256x192.py b/configs/top_down/resnet/coco/res152_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/coco/res152_coco_384x288.py b/configs/top_down/resnet/coco/res152_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/coco/res50_coco_384x288.py b/configs/top_down/resnet/coco/res50_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/ochuman/res101_ochuman_256x192.py b/configs/top_down/resnet/ochuman/res101_ochuman_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/ochuman/res101_ochuman_384x288.py b/configs/top_down/resnet/ochuman/res101_ochuman_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/ochuman/res152_ochuman_256x192.py b/configs/top_down/resnet/ochuman/res152_ochuman_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/ochuman/res152_ochuman_384x288.py b/configs/top_down/resnet/ochuman/res152_ochuman_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnet/ochuman/res50_ochuman_384x288.py b/configs/top_down/resnet/ochuman/res50_ochuman_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py b/configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py b/configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py b/configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py b/configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py b/configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnext/coco/resnext101_coco_256x192.py b/configs/top_down/resnext/coco/resnext101_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnext/coco/resnext101_coco_384x288.py b/configs/top_down/resnext/coco/resnext101_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnext/coco/resnext152_coco_256x192.py b/configs/top_down/resnext/coco/resnext152_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnext/coco/resnext152_coco_384x288.py b/configs/top_down/resnext/coco/resnext152_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/resnext/coco/resnext50_coco_384x288.py b/configs/top_down/resnext/coco/resnext50_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/scnet/coco/scnet101_coco_256x192.py b/configs/top_down/scnet/coco/scnet101_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/scnet/coco/scnet101_coco_384x288.py b/configs/top_down/scnet/coco/scnet101_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/scnet/coco/scnet50_coco_256x192.py b/configs/top_down/scnet/coco/scnet50_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/scnet/coco/scnet50_coco_384x288.py b/configs/top_down/scnet/coco/scnet50_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/seresnet/coco/seresnet101_coco_256x192.py b/configs/top_down/seresnet/coco/seresnet101_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/seresnet/coco/seresnet101_coco_384x288.py b/configs/top_down/seresnet/coco/seresnet101_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/seresnet/coco/seresnet152_coco_256x192.py b/configs/top_down/seresnet/coco/seresnet152_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/seresnet/coco/seresnet152_coco_384x288.py b/configs/top_down/seresnet/coco/seresnet152_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/seresnet/coco/seresnet50_coco_384x288.py b/configs/top_down/seresnet/coco/seresnet50_coco_384x288.py old mode 100755 new mode 100644 diff --git a/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py b/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py old mode 100755 new mode 100644 diff --git a/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py b/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py old mode 100755 new mode 100644 From 30e0c8a1e0365b631846bf37c36b402e0f1b90f8 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Tue, 4 Aug 2020 18:40:56 +0800 Subject: [PATCH 02/25] init aic --- .../datasets/top_down/topdown_aic_dataset.py | 393 ++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 mmpose/datasets/datasets/top_down/topdown_aic_dataset.py diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py new file mode 100644 index 0000000000..581689173f --- /dev/null +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -0,0 +1,393 @@ +import os +from collections import OrderedDict, defaultdict + +import json_tricks as json +import numpy as np +from pycocotools.coco import COCO +from pycocotools.cocoeval import COCOeval + +from ....core.post_processing import oks_nms, soft_oks_nms +from ...registry import DATASETS +from .topdown_base_dataset import TopDownBaseDataset + + +def _get_mapping_id_name(imgs): + """ + Args: + imgs (list): list of image info. + Returns: + id2name (dict): mapping image id to name. + name2id (dict): mapping image name to id. + """ + id2name = {} + name2id = {} + for image in imgs: + file_name = image['file_name'] + image_id = image['id'] + id2name[image_id] = file_name + name2id[file_name] = image_id + + return id2name, name2id + + +@DATASETS.register_module() +class TopDownAicDataset(TopDownBaseDataset): + """AicDataset dataset for top-down pose estimation. + + `AI Challenger : A Large-scale Dataset for Going Deeper + in Image Understanding `_ + + The dataset loads raw features and apply specified transforms + to return a dict containing the image tensors and other information. + + AIC keypoint indexes:: + 0: "right_shoulder", + 1: "right_elbow", + 2: "right_wrist", + 3: "left_shoulder", + 4: "left_elbow", + 5: "left_wrist", + 6: "right_hip", + 7: "right_knee", + 8: "right_ankle", + 9: "left_hip", + 10: "left_knee", + 11: "left_ankle", + 12: "head_top", + 13: "neck" + + Args: + ann_file (str): Path to the annotation file. + img_prefix (str): Path to a directory where images are held. + Default: None. + data_cfg (dict): config + pipeline (list[dict | callable]): A sequence of data transforms. + test_mode (bool): Store True when building test or + validation dataset. Default: False. + """ + + def __init__(self, + ann_file, + img_prefix, + data_cfg, + pipeline, + test_mode=False): + super().__init__( + ann_file, img_prefix, data_cfg, pipeline, test_mode=test_mode) + + self.use_gt_bbox = data_cfg['use_gt_bbox'] + self.bbox_file = data_cfg['bbox_file'] + self.image_thr = data_cfg['image_thr'] + + self.soft_nms = data_cfg['soft_nms'] + self.nms_thr = data_cfg['nms_thr'] + self.oks_thr = data_cfg['oks_thr'] + self.vis_thr = data_cfg['vis_thr'] + self.bbox_thr = data_cfg['bbox_thr'] + + self.ann_info['flip_pairs'] = [[0, 3], [1, 4], [2, 5], [6, 9], [7, 10], + [8, 11]] + + self.ann_info['upper_body_ids'] = (0, 1, 2, 3, 4, 5, 12, 13) + self.ann_info['lower_body_ids'] = (6, 7, 8, 9, 10, 11) + + self.ann_info['use_different_joints_weight'] = False + self.ann_info['joints_weight'] = np.array( + [ + 1., + 1.2, + 1.5, + 1., + 1.2, + 1.5, + 1., + 1.2, + 1.5, + 1., + 1.2, + 1.5, + 1., + 1., + ], + dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) + + self.coco = COCO(ann_file) + + cats = [ + cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds()) + ] + self.classes = ['__background__'] + cats + self.num_classes = len(self.classes) + + self.id2name, self.name2id = _get_mapping_id_name(self.coco.imgs) + self._class_to_ind = dict(zip(self.classes, range(self.num_classes))) + self._class_to_coco_ind = dict(zip(cats, self.coco.getCatIds())) + self._coco_ind_to_class_ind = dict([(self._class_to_coco_ind[cls], + self._class_to_ind[cls]) + for cls in self.classes[1:]]) + self.image_set_index = self.coco.getImgIds() + self.num_images = len(self.image_set_index) + self.db = self._get_db() + + print(f'=> num_images: {self.num_images}') + print(f'=> load {len(self.db)} samples') + + def _get_db(self): + """Load dataset.""" + assert self.use_gt_bbox, 'Only gt bbox train/test is supported.' + # use ground truth bbox + gt_db = self._load_coco_keypoint_annotations() + return gt_db + + def _load_coco_keypoint_annotations(self): + """Ground truth bbox and keypoints.""" + gt_db = [] + for index in self.image_set_index: + gt_db.extend(self._load_coco_keypoint_annotation_kernal(index)) + return gt_db + + def _load_coco_keypoint_annotation_kernal(self, index): + """load annotation from COCOAPI. + + Note: + bbox:[x1, y1, w, h] + Args: + index: coco image id + Returns: + db entry + """ + im_ann = self.coco.loadImgs(index)[0] + width = im_ann['width'] + height = im_ann['height'] + num_joints = self.ann_info['num_joints'] + + ann_ids = self.coco.getAnnIds(imgIds=index, iscrowd=False) + objs = self.coco.loadAnns(ann_ids) + + # sanitize bboxes + valid_objs = [] + for obj in objs: + x, y, w, h = obj['bbox'] + x1 = max(0, x) + y1 = max(0, y) + x2 = min(width - 1, x1 + max(0, w - 1)) + y2 = min(height - 1, y1 + max(0, h - 1)) + if obj['area'] > 0 and x2 >= x1 and y2 >= y1: + obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1] + valid_objs.append(obj) + objs = valid_objs + + rec = [] + for obj in objs: + if max(obj['keypoints']) == 0: + continue + joints_3d = np.zeros((num_joints, 3), dtype=np.float) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + for ipt in range(num_joints): + joints_3d[ipt, 0] = obj['keypoints'][ipt * 3 + 0] + joints_3d[ipt, 1] = obj['keypoints'][ipt * 3 + 1] + joints_3d[ipt, 2] = 0 + t_vis = obj['keypoints'][ipt * 3 + 2] + if t_vis > 1: + t_vis = 1 + joints_3d_visible[ipt, 0] = t_vis + joints_3d_visible[ipt, 1] = t_vis + joints_3d_visible[ipt, 2] = 0 + center, scale = self._box2cs(obj['clean_bbox'][:4]) + rec.append({ + 'image_file': + os.path.join(self.img_prefix, self.id2name[index]), + 'center': + center, + 'scale': + scale, + 'rotation': + 0, + 'joints_3d': + joints_3d, + 'joints_3d_visible': + joints_3d_visible, + 'dataset': + 'aic', + 'bbox_score': + 1 + }) + return rec + + def _box2cs(self, box): + """Get box center & scale given box (x, y, w, h).""" + x, y, w, h = box[:4] + return self._xywh2cs(x, y, w, h) + + def _xywh2cs(self, x, y, w, h): + """This encodes bbox(x,y,w,w) into (center, scale) + + Args: + x, y, w, h + + Returns: + center (np.ndarray[float32](2,)): center of the bbox (x, y). + scale (np.ndarray[float32](2,)): scale of the bbox w & h. + """ + aspect_ratio = self.ann_info['image_size'][0] / self.ann_info[ + 'image_size'][1] + center = np.array([x + w * 0.5, y + h * 0.5], dtype=np.float32) + + if (not self.test_mode) and np.random.rand() < 0.3: + center += 0.4 * (np.random.rand(2) - 0.5) * [w, h] + + if w > aspect_ratio * h: + h = w * 1.0 / aspect_ratio + elif w < aspect_ratio * h: + w = h * aspect_ratio + + # pixel std is 200.0 + scale = np.array([w / 200.0, h / 200.0], dtype=np.float32) + + scale = scale * 1.25 + + return center, scale + + def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): + """Evaluate coco keypoint results. The pose prediction results will be + saved in `${res_folder}/result_keypoints.json`. + + Note: + num_keypoints: K + + Args: + outputs (list(preds, boxes, image_path)) + :preds (np.ndarray[1,K,3]): The first two dimensions are + coordinates, score is the third dimension of the array. + :boxes (np.ndarray[1,6]): [center[0], center[1], scale[0] + , scale[1],area, score] + :image_path (list[str]): For example, [ '/', 'v','a', 'l', + '2', '0', '1', '7', '/', '0', '0', '0', '0', '0', + '0', '3', '9', '7', '1', '3', '3', '.', 'j', 'p', 'g'] + res_folder (str): Path of directory to save the results. + metric (str): Metric to be performed. Defaults: 'mAP'. + + Returns: + name_value (dict): Evaluation results for evaluation metric. + """ + assert metric == 'mAP' + + res_file = os.path.join(res_folder, 'result_keypoints.json') + + kpts = defaultdict(list) + for preds, boxes, image_path in outputs: + str_image_path = ''.join(image_path) + image_id = self.name2id(str_image_path) + + kpts[image_id].append({ + 'keypoints': preds[0], + 'center': boxes[0][0:2], + 'scale': boxes[0][2:4], + 'area': boxes[0][4], + 'score': boxes[0][5], + 'image_id': image_id, + }) + + # rescoring and oks nms + num_joints = self.ann_info['num_joints'] + vis_thr = self.vis_thr + oks_thr = self.oks_thr + oks_nmsed_kpts = [] + for img in kpts.keys(): + img_kpts = kpts[img] + for n_p in img_kpts: + box_score = n_p['score'] + kpt_score = 0 + valid_num = 0 + for n_jt in range(0, num_joints): + t_s = n_p['keypoints'][n_jt][2] + if t_s > vis_thr: + kpt_score = kpt_score + t_s + valid_num = valid_num + 1 + if valid_num != 0: + kpt_score = kpt_score / valid_num + # rescoring + n_p['score'] = kpt_score * box_score + + if self.soft_nms: + keep = soft_oks_nms( + [img_kpts[i] for i in range(len(img_kpts))], oks_thr) + else: + keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))], + oks_thr) + + if len(keep) == 0: + oks_nmsed_kpts.append(img_kpts) + else: + oks_nmsed_kpts.append([img_kpts[_keep] for _keep in keep]) + + self._write_coco_keypoint_results(oks_nmsed_kpts, res_file) + + info_str = self._do_python_keypoint_eval(res_file) + name_value = OrderedDict(info_str) + + return name_value + + def _write_coco_keypoint_results(self, keypoints, res_file): + """Write results into a json file.""" + data_pack = [{ + 'cat_id': self._class_to_coco_ind[cls], + 'cls_ind': cls_ind, + 'cls': cls, + 'ann_type': 'keypoints', + 'keypoints': keypoints + } for cls_ind, cls in enumerate(self.classes) + if not cls == '__background__'] + + results = self._coco_keypoint_results_one_category_kernel(data_pack[0]) + + with open(res_file, 'w') as f: + json.dump(results, f, sort_keys=True, indent=4) + + def _coco_keypoint_results_one_category_kernel(self, data_pack): + """Get coco keypoint results.""" + cat_id = data_pack['cat_id'] + keypoints = data_pack['keypoints'] + cat_results = [] + + for img_kpts in keypoints: + if len(img_kpts) == 0: + continue + + _key_points = np.array( + [img_kpt['keypoints'] for img_kpt in img_kpts]) + key_points = _key_points.reshape(-1, + self.ann_info['num_joints'] * 3) + + result = [{ + 'image_id': img_kpt['image_id'], + 'category_id': cat_id, + 'keypoints': list(key_point), + 'score': img_kpt['score'], + 'center': list(img_kpt['center']), + 'scale': list(img_kpt['scale']) + } for img_kpt, key_point in zip(img_kpts, key_points)] + + cat_results.extend(result) + + return cat_results + + def _do_python_keypoint_eval(self, res_file): + """Keypoint evaluation using COCOAPI.""" + coco_dt = self.coco.loadRes(res_file) + coco_eval = COCOeval(self.coco, coco_dt, 'keypoints') + coco_eval.params.useSegm = None + coco_eval.evaluate() + coco_eval.accumulate() + coco_eval.summarize() + + stats_names = [ + 'AP', 'Ap .5', 'AP .75', 'AP (M)', 'AP (L)', 'AR', 'AR .5', + 'AR .75', 'AR (M)', 'AR (L)' + ] + + info_str = [] + for ind, name in enumerate(stats_names): + info_str.append((name, coco_eval.stats[ind])) + + return info_str From 221246e7e6e361133071d8a2705c55cd47c38668 Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 17:34:36 +0800 Subject: [PATCH 03/25] add cocoapi --- .../datasets/datasets/top_down/topdown_aic_dataset.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 581689173f..a61d3f6217 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -111,7 +111,7 @@ def __init__(self, ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) - self.coco = COCO(ann_file) + self.coco = COCO(test_num_keypoints=14, annotation_file=ann_file) cats = [ cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds()) @@ -374,8 +374,14 @@ def _coco_keypoint_results_one_category_kernel(self, data_pack): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" + + sigmas = np.array([ + 0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, + 0.01402144, 0.03909642, 0.03686941, 0.01981803, 0.03843971, + 0.03412318, 0.02415081, 0.01291456, 0.01236173 + ]) coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(self.coco, coco_dt, 'keypoints') + coco_eval = COCOeval(sigmas, self.coco, coco_dt, 'keypoints') coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() From 57c9542b7c1dfd68d6eb8009807690e3b23ea177 Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 18:05:32 +0800 Subject: [PATCH 04/25] add aic cfg --- .../hrnet/aic/hrnet_w32_aic_256x192.py | 177 +++++++++++++++++ .../hrnet/aic/hrnet_w32_aic_384x288.py | 177 +++++++++++++++++ .../hrnet/aic/hrnet_w48_aic_256x192.py | 177 +++++++++++++++++ .../hrnet/aic/hrnet_w48_aic_384x288.py | 178 ++++++++++++++++++ .../top_down/resnet/aic/res101_aic_256x192.py | 147 +++++++++++++++ .../top_down/resnet/aic/res101_aic_384x288.py | 147 +++++++++++++++ .../top_down/resnet/aic/res152_aic_256x192.py | 147 +++++++++++++++ .../top_down/resnet/aic/res152_aic_384x288.py | 147 +++++++++++++++ .../top_down/resnet/aic/res50_aic_256x192.py | 146 ++++++++++++++ .../top_down/resnet/aic/res50_aic_384x288.py | 147 +++++++++++++++ 10 files changed, 1590 insertions(+) create mode 100644 configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py create mode 100755 configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py create mode 100755 configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py create mode 100755 configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py create mode 100755 configs/top_down/resnet/aic/res101_aic_256x192.py create mode 100755 configs/top_down/resnet/aic/res101_aic_384x288.py create mode 100755 configs/top_down/resnet/aic/res152_aic_256x192.py create mode 100755 configs/top_down/resnet/aic/res152_aic_384x288.py create mode 100644 configs/top_down/resnet/aic/res50_aic_256x192.py create mode 100755 configs/top_down/resnet/aic/res50_aic_384x288.py diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py new file mode 100644 index 0000000000..2fab5ed065 --- /dev/null +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py @@ -0,0 +1,177 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=1) +evaluation = dict(interval=1, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/hrnet_w32-36af842e.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(32, 64)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(32, 64, 128)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(32, 64, 128, 256))), + ), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=32, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/coco/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py new file mode 100755 index 0000000000..29413c56a6 --- /dev/null +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py @@ -0,0 +1,177 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=5) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/hrnet_w32-36af842e.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(32, 64)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(32, 64, 128)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(32, 64, 128, 256))), + ), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=32, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[288, 384], + heatmap_size=[72, 96], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=3), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py new file mode 100755 index 0000000000..f3f2216da2 --- /dev/null +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py @@ -0,0 +1,177 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=5) +evaluation = dict(interval=10, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/hrnet_w48-8ef0771d.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(48, 96)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(48, 96, 192)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(48, 96, 192, 384))), + ), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=48, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py new file mode 100755 index 0000000000..8cc8c79ac4 --- /dev/null +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py @@ -0,0 +1,178 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=5) +evaluation = dict(interval=10, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup=None, + # warmup='linear', + # warmup_iters=500, + # warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/hrnet_w48-8ef0771d.pth', + backbone=dict( + type='HRNet', + in_channels=3, + extra=dict( + stage1=dict( + num_modules=1, + num_branches=1, + block='BOTTLENECK', + num_blocks=(4, ), + num_channels=(64, )), + stage2=dict( + num_modules=1, + num_branches=2, + block='BASIC', + num_blocks=(4, 4), + num_channels=(48, 96)), + stage3=dict( + num_modules=4, + num_branches=3, + block='BASIC', + num_blocks=(4, 4, 4), + num_channels=(48, 96, 192)), + stage4=dict( + num_modules=3, + num_branches=4, + block='BASIC', + num_blocks=(4, 4, 4, 4), + num_channels=(48, 96, 192, 384))), + ), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=48, + out_channels=channel_cfg['num_output_channels'], + num_deconv_layers=0, + extra=dict(final_conv_kernel=1, ), + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[288, 384], + heatmap_size=[72, 96], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=3), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res101_aic_256x192.py b/configs/top_down/resnet/aic/res101_aic_256x192.py new file mode 100755 index 0000000000..2f66e282ee --- /dev/null +++ b/configs/top_down/resnet/aic/res101_aic_256x192.py @@ -0,0 +1,147 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet101-5d3b4d8f.pth', + backbone=dict(type='ResNet', depth=101), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res101_aic_384x288.py b/configs/top_down/resnet/aic/res101_aic_384x288.py new file mode 100755 index 0000000000..76c289e24e --- /dev/null +++ b/configs/top_down/resnet/aic/res101_aic_384x288.py @@ -0,0 +1,147 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet101-5d3b4d8f.pth', + backbone=dict(type='ResNet', depth=101), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[288, 384], + heatmap_size=[72, 96], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=3), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res152_aic_256x192.py b/configs/top_down/resnet/aic/res152_aic_256x192.py new file mode 100755 index 0000000000..ce952abd3a --- /dev/null +++ b/configs/top_down/resnet/aic/res152_aic_256x192.py @@ -0,0 +1,147 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet152-b121ed2d.pth', + backbone=dict(type='ResNet', depth=152), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res152_aic_384x288.py b/configs/top_down/resnet/aic/res152_aic_384x288.py new file mode 100755 index 0000000000..8dc3315359 --- /dev/null +++ b/configs/top_down/resnet/aic/res152_aic_384x288.py @@ -0,0 +1,147 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet152-b121ed2d.pth', + backbone=dict(type='ResNet', depth=152), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[288, 384], + heatmap_size=[72, 96], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=3), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=32, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res50_aic_256x192.py b/configs/top_down/resnet/aic/res50_aic_256x192.py new file mode 100644 index 0000000000..94cd35360a --- /dev/null +++ b/configs/top_down/resnet/aic/res50_aic_256x192.py @@ -0,0 +1,146 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=1, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet50-19c8e357.pth', + backbone=dict(type='ResNet', depth=50), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=True, + image_thr=0.0, + bbox_file='', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=2), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) diff --git a/configs/top_down/resnet/aic/res50_aic_384x288.py b/configs/top_down/resnet/aic/res50_aic_384x288.py new file mode 100755 index 0000000000..1b1c7373c3 --- /dev/null +++ b/configs/top_down/resnet/aic/res50_aic_384x288.py @@ -0,0 +1,147 @@ +log_level = 'INFO' +load_from = None +resume_from = None +dist_params = dict(backend='nccl') +workflow = [('train', 1)] +checkpoint_config = dict(interval=10) +evaluation = dict(interval=5, metric='mAP') + +optimizer = dict( + type='Adam', + lr=5e-4, +) +optimizer_config = dict(grad_clip=None) +# learning policy +lr_config = dict( + policy='step', + warmup='linear', + warmup_iters=500, + warmup_ratio=0.001, + step=[170, 200]) +total_epochs = 210 +log_config = dict( + interval=50, + hooks=[ + dict(type='TextLoggerHook'), + # dict(type='TensorboardLoggerHook') + ]) + +channel_cfg = dict( + num_output_channels=17, + dataset_joints=17, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + ], + inference_channel=[ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 + ]) + +# model settings +model = dict( + type='TopDown', + pretrained='models/pytorch/imagenet/resnet50-19c8e357.pth', + backbone=dict(type='ResNet', depth=50), + keypoint_head=dict( + type='TopDownSimpleHead', + in_channels=2048, + out_channels=channel_cfg['num_output_channels'], + ), + train_cfg=dict(), + test_cfg=dict( + flip_test=True, + post_process=True, + shift_heatmap=True, + unbiased_decoding=False, + modulate_kernel=11), + loss_pose=dict(type='JointsMSELoss', use_target_weight=True)) + +data_cfg = dict( + image_size=[288, 384], + heatmap_size=[72, 96], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=False, + image_thr=0.0, + bbox_file='data/person_detection_results/' + 'COCO_val2017_detections_AP_H_56_person.json', +) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownRandomFlip', flip_prob=0.5), + dict( + type='TopDownHalfBodyTransform', + num_joints_half_body=8, + prob_half_body=0.3), + dict( + type='TopDownGetRandomScaleRotation', rot_factor=40, scale_factor=0.5), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict(type='TopDownGenerateTarget', sigma=3), + dict( + type='Collect', + keys=['img', 'target', 'target_weight'], + meta_keys=[ + 'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale', + 'rotation', 'bbox_score', 'flip_pairs' + ]), +] + +valid_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='TopDownAffine'), + dict(type='ToTensor'), + dict( + type='NormalizeTensor', + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225]), + dict( + type='Collect', + keys=[ + 'img', + ], + meta_keys=[ + 'image_file', 'center', 'scale', 'rotation', 'bbox_score', + 'flip_pairs' + ]), +] + +test_pipeline = valid_pipeline + +data_root = 'data/aic' +data = dict( + samples_per_gpu=64, + workers_per_gpu=2, + train=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_train.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' + 'keypoint_train_images_20170902/', + data_cfg=data_cfg, + pipeline=train_pipeline), + val=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), + test=dict( + type='TopDownCocoDataset', + ann_file=f'{data_root}/annotations/aic_val.json', + img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' + 'keypoint_validation_images_20170911/', + data_cfg=data_cfg, + pipeline=valid_pipeline), +) From ffd03cd0642215e0fece029bd0a05a75aed86b0d Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 18:16:33 +0800 Subject: [PATCH 05/25] fix aic cfg --- configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py | 10 ++++------ configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py | 10 ++++------ configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py | 10 ++++------ configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py | 10 ++++------ configs/top_down/resnet/aic/res101_aic_256x192.py | 10 ++++------ configs/top_down/resnet/aic/res101_aic_384x288.py | 10 ++++------ configs/top_down/resnet/aic/res152_aic_256x192.py | 10 ++++------ configs/top_down/resnet/aic/res152_aic_384x288.py | 10 ++++------ configs/top_down/resnet/aic/res50_aic_256x192.py | 10 ++++------ configs/top_down/resnet/aic/res50_aic_384x288.py | 10 ++++------ 10 files changed, 40 insertions(+), 60 deletions(-) diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py index 2fab5ed065..f31608ba80 100644 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py index 29413c56a6..d1656f0726 100755 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py index f3f2216da2..9e32f5f5bd 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py index 8cc8c79ac4..f55265d1db 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py @@ -28,14 +28,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res101_aic_256x192.py b/configs/top_down/resnet/aic/res101_aic_256x192.py index 2f66e282ee..3fe0fcf88e 100755 --- a/configs/top_down/resnet/aic/res101_aic_256x192.py +++ b/configs/top_down/resnet/aic/res101_aic_256x192.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res101_aic_384x288.py b/configs/top_down/resnet/aic/res101_aic_384x288.py index 76c289e24e..ba6a0e388f 100755 --- a/configs/top_down/resnet/aic/res101_aic_384x288.py +++ b/configs/top_down/resnet/aic/res101_aic_384x288.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res152_aic_256x192.py b/configs/top_down/resnet/aic/res152_aic_256x192.py index ce952abd3a..b5eb051009 100755 --- a/configs/top_down/resnet/aic/res152_aic_256x192.py +++ b/configs/top_down/resnet/aic/res152_aic_256x192.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res152_aic_384x288.py b/configs/top_down/resnet/aic/res152_aic_384x288.py index 8dc3315359..8ab397b945 100755 --- a/configs/top_down/resnet/aic/res152_aic_384x288.py +++ b/configs/top_down/resnet/aic/res152_aic_384x288.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res50_aic_256x192.py b/configs/top_down/resnet/aic/res50_aic_256x192.py index 94cd35360a..9c63bb8a09 100644 --- a/configs/top_down/resnet/aic/res50_aic_256x192.py +++ b/configs/top_down/resnet/aic/res50_aic_256x192.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( diff --git a/configs/top_down/resnet/aic/res50_aic_384x288.py b/configs/top_down/resnet/aic/res50_aic_384x288.py index 1b1c7373c3..e6c25b639b 100755 --- a/configs/top_down/resnet/aic/res50_aic_384x288.py +++ b/configs/top_down/resnet/aic/res50_aic_384x288.py @@ -27,14 +27,12 @@ ]) channel_cfg = dict( - num_output_channels=17, - dataset_joints=17, + num_output_channels=14, + dataset_joints=14, dataset_channel=[ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], ], - inference_channel=[ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 - ]) + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) # model settings model = dict( From 9260f2cc04f632a0ea76744554f3246d593dacc3 Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 18:20:43 +0800 Subject: [PATCH 06/25] fix aic cfg --- configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py | 6 +++--- configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py | 6 +++--- configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py | 6 +++--- configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py | 6 +++--- configs/top_down/resnet/aic/res101_aic_256x192.py | 6 +++--- configs/top_down/resnet/aic/res101_aic_384x288.py | 6 +++--- configs/top_down/resnet/aic/res152_aic_256x192.py | 6 +++--- configs/top_down/resnet/aic/res152_aic_384x288.py | 6 +++--- configs/top_down/resnet/aic/res50_aic_256x192.py | 6 +++--- configs/top_down/resnet/aic/res50_aic_384x288.py | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py index f31608ba80..99ec61652a 100644 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py @@ -152,21 +152,21 @@ samples_per_gpu=64, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py index d1656f0726..3d5c9f9e74 100755 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py @@ -152,21 +152,21 @@ samples_per_gpu=64, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py index 9e32f5f5bd..b74106b722 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py @@ -152,21 +152,21 @@ samples_per_gpu=32, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py index f55265d1db..f20a96649f 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py @@ -153,21 +153,21 @@ samples_per_gpu=32, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res101_aic_256x192.py b/configs/top_down/resnet/aic/res101_aic_256x192.py index 3fe0fcf88e..a316815d30 100755 --- a/configs/top_down/resnet/aic/res101_aic_256x192.py +++ b/configs/top_down/resnet/aic/res101_aic_256x192.py @@ -122,21 +122,21 @@ samples_per_gpu=64, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res101_aic_384x288.py b/configs/top_down/resnet/aic/res101_aic_384x288.py index ba6a0e388f..9853fbae72 100755 --- a/configs/top_down/resnet/aic/res101_aic_384x288.py +++ b/configs/top_down/resnet/aic/res101_aic_384x288.py @@ -122,21 +122,21 @@ samples_per_gpu=32, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res152_aic_256x192.py b/configs/top_down/resnet/aic/res152_aic_256x192.py index b5eb051009..e7046303b2 100755 --- a/configs/top_down/resnet/aic/res152_aic_256x192.py +++ b/configs/top_down/resnet/aic/res152_aic_256x192.py @@ -122,21 +122,21 @@ samples_per_gpu=32, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res152_aic_384x288.py b/configs/top_down/resnet/aic/res152_aic_384x288.py index 8ab397b945..aed9d4a8cc 100755 --- a/configs/top_down/resnet/aic/res152_aic_384x288.py +++ b/configs/top_down/resnet/aic/res152_aic_384x288.py @@ -122,21 +122,21 @@ samples_per_gpu=32, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res50_aic_256x192.py b/configs/top_down/resnet/aic/res50_aic_256x192.py index 9c63bb8a09..9a86b00401 100644 --- a/configs/top_down/resnet/aic/res50_aic_256x192.py +++ b/configs/top_down/resnet/aic/res50_aic_256x192.py @@ -121,21 +121,21 @@ samples_per_gpu=64, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', diff --git a/configs/top_down/resnet/aic/res50_aic_384x288.py b/configs/top_down/resnet/aic/res50_aic_384x288.py index e6c25b639b..e6affae2ac 100755 --- a/configs/top_down/resnet/aic/res50_aic_384x288.py +++ b/configs/top_down/resnet/aic/res50_aic_384x288.py @@ -122,21 +122,21 @@ samples_per_gpu=64, workers_per_gpu=2, train=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_train.json', img_prefix=f'{data_root}/ai_challenger_keypoint_train_20170902/' 'keypoint_train_images_20170902/', data_cfg=data_cfg, pipeline=train_pipeline), val=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', data_cfg=data_cfg, pipeline=valid_pipeline), test=dict( - type='TopDownCocoDataset', + type='TopDownAicDataset', ann_file=f'{data_root}/annotations/aic_val.json', img_prefix=f'{data_root}/ai_challenger_keypoint_validation_20170911/' 'keypoint_validation_images_20170911/', From 5e912840ce32d2fb538b2e2de93671465c80ab0b Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 18:22:29 +0800 Subject: [PATCH 07/25] add TopDownAicDataset --- mmpose/datasets/datasets/__init__.py | 4 +- mmpose/datasets/datasets/top_down/__init__.py | 6 +- .../datasets/top_down/topdown_aic_dataset.py | 160 ++++-------------- 3 files changed, 37 insertions(+), 133 deletions(-) diff --git a/mmpose/datasets/datasets/__init__.py b/mmpose/datasets/datasets/__init__.py index 50dc58578d..735ea64d52 100644 --- a/mmpose/datasets/datasets/__init__.py +++ b/mmpose/datasets/datasets/__init__.py @@ -1,10 +1,10 @@ from .bottom_up import BottomUpCocoDataset from .top_down import (TopDownCocoDataset, TopDownMpiiDataset, TopDownMpiiTrbDataset, TopDownOCHumanDataset, - TopDownOneHand10KDataset) + TopDownOneHand10KDataset, TopDownAicDataset) __all__ = [ 'TopDownCocoDataset', 'BottomUpCocoDataset', 'TopDownMpiiDataset', 'TopDownMpiiTrbDataset', 'TopDownOneHand10KDataset', - 'TopDownOCHumanDataset' + 'TopDownOCHumanDataset', 'TopDownAicDataset' ] diff --git a/mmpose/datasets/datasets/top_down/__init__.py b/mmpose/datasets/datasets/top_down/__init__.py index 72d6c6b6d1..f408c0b3dd 100644 --- a/mmpose/datasets/datasets/top_down/__init__.py +++ b/mmpose/datasets/datasets/top_down/__init__.py @@ -1,10 +1,12 @@ +from .topdown_aic_dataset import TopDownAicDataset from .topdown_coco_dataset import TopDownCocoDataset from .topdown_mpii_dataset import TopDownMpiiDataset from .topdown_mpii_trb_dataset import TopDownMpiiTrbDataset from .topdown_ochuman_dataset import TopDownOCHumanDataset from .topdown_onehand10k_dataset import TopDownOneHand10KDataset + __all__ = [ 'TopDownCocoDataset', 'TopDownMpiiTrbDataset', 'TopDownMpiiDataset', - 'TopDownOneHand10KDataset', 'TopDownOCHumanDataset' -] + 'TopDownOneHand10KDataset', 'TopDownOCHumanDataset', 'TopDownAicDataset' +] \ No newline at end of file diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index a61d3f6217..443e99e737 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -1,29 +1,27 @@ import os from collections import OrderedDict, defaultdict -import json_tricks as json import numpy as np from pycocotools.coco import COCO from pycocotools.cocoeval import COCOeval from ....core.post_processing import oks_nms, soft_oks_nms from ...registry import DATASETS -from .topdown_base_dataset import TopDownBaseDataset +from .topdown_coco_dataset import TopDownCocoDataset def _get_mapping_id_name(imgs): """ Args: - imgs (list): list of image info. + imgs (dict): dict of image info. Returns: id2name (dict): mapping image id to name. name2id (dict): mapping image name to id. """ id2name = {} name2id = {} - for image in imgs: + for image_id, image in imgs.items(): file_name = image['file_name'] - image_id = image['id'] id2name[image_id] = file_name name2id[file_name] = image_id @@ -31,7 +29,7 @@ def _get_mapping_id_name(imgs): @DATASETS.register_module() -class TopDownAicDataset(TopDownBaseDataset): +class TopDownAicDataset(TopDownCocoDataset): """AicDataset dataset for top-down pose estimation. `AI Challenger : A Large-scale Dataset for Going Deeper @@ -72,7 +70,7 @@ def __init__(self, data_cfg, pipeline, test_mode=False): - super().__init__( + super(TopDownCocoDataset, self).__init__( ann_file, img_prefix, data_cfg, pipeline, test_mode=test_mode) self.use_gt_bbox = data_cfg['use_gt_bbox'] @@ -91,8 +89,8 @@ def __init__(self, self.ann_info['upper_body_ids'] = (0, 1, 2, 3, 4, 5, 12, 13) self.ann_info['lower_body_ids'] = (6, 7, 8, 9, 10, 11) - self.ann_info['use_different_joints_weight'] = False - self.ann_info['joints_weight'] = np.array( + self.ann_info['use_different_joint_weights'] = False + self.ann_info['joint_weights'] = np.array( [ 1., 1.2, @@ -118,15 +116,15 @@ def __init__(self, ] self.classes = ['__background__'] + cats self.num_classes = len(self.classes) - - self.id2name, self.name2id = _get_mapping_id_name(self.coco.imgs) self._class_to_ind = dict(zip(self.classes, range(self.num_classes))) self._class_to_coco_ind = dict(zip(cats, self.coco.getCatIds())) - self._coco_ind_to_class_ind = dict([(self._class_to_coco_ind[cls], - self._class_to_ind[cls]) - for cls in self.classes[1:]]) + self._coco_ind_to_class_ind = dict( + (self._class_to_coco_ind[cls], self._class_to_ind[cls]) + for cls in self.classes[1:]) self.image_set_index = self.coco.getImgIds() self.num_images = len(self.image_set_index) + self.id2name, self.name2id = _get_mapping_id_name(self.coco.imgs) + self.db = self._get_db() print(f'=> num_images: {self.num_images}') @@ -134,19 +132,11 @@ def __init__(self, def _get_db(self): """Load dataset.""" - assert self.use_gt_bbox, 'Only gt bbox train/test is supported.' - # use ground truth bbox + assert self.use_gt_bbox gt_db = self._load_coco_keypoint_annotations() return gt_db - def _load_coco_keypoint_annotations(self): - """Ground truth bbox and keypoints.""" - gt_db = [] - for index in self.image_set_index: - gt_db.extend(self._load_coco_keypoint_annotation_kernal(index)) - return gt_db - - def _load_coco_keypoint_annotation_kernal(self, index): + def _load_coco_keypoint_annotation_kernel(self, index): """load annotation from COCOAPI. Note: @@ -183,70 +173,26 @@ def _load_coco_keypoint_annotation_kernal(self, index): continue joints_3d = np.zeros((num_joints, 3), dtype=np.float) joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) - for ipt in range(num_joints): - joints_3d[ipt, 0] = obj['keypoints'][ipt * 3 + 0] - joints_3d[ipt, 1] = obj['keypoints'][ipt * 3 + 1] - joints_3d[ipt, 2] = 0 - t_vis = obj['keypoints'][ipt * 3 + 2] - if t_vis > 1: - t_vis = 1 - joints_3d_visible[ipt, 0] = t_vis - joints_3d_visible[ipt, 1] = t_vis - joints_3d_visible[ipt, 2] = 0 - center, scale = self._box2cs(obj['clean_bbox'][:4]) - rec.append({ - 'image_file': - os.path.join(self.img_prefix, self.id2name[index]), - 'center': - center, - 'scale': - scale, - 'rotation': - 0, - 'joints_3d': - joints_3d, - 'joints_3d_visible': - joints_3d_visible, - 'dataset': - 'aic', - 'bbox_score': - 1 - }) - return rec - - def _box2cs(self, box): - """Get box center & scale given box (x, y, w, h).""" - x, y, w, h = box[:4] - return self._xywh2cs(x, y, w, h) - - def _xywh2cs(self, x, y, w, h): - """This encodes bbox(x,y,w,w) into (center, scale) - - Args: - x, y, w, h - Returns: - center (np.ndarray[float32](2,)): center of the bbox (x, y). - scale (np.ndarray[float32](2,)): scale of the bbox w & h. - """ - aspect_ratio = self.ann_info['image_size'][0] / self.ann_info[ - 'image_size'][1] - center = np.array([x + w * 0.5, y + h * 0.5], dtype=np.float32) - - if (not self.test_mode) and np.random.rand() < 0.3: - center += 0.4 * (np.random.rand(2) - 0.5) * [w, h] - - if w > aspect_ratio * h: - h = w * 1.0 / aspect_ratio - elif w < aspect_ratio * h: - w = h * aspect_ratio + keypoints = np.array(obj['keypoints']).reshape(-1, 3) + joints_3d[:, :2] = keypoints[:, :2] + joints_3d_visible[:, :2] = np.minimum(1, keypoints[:, 2:3]) - # pixel std is 200.0 - scale = np.array([w / 200.0, h / 200.0], dtype=np.float32) + center, scale = self._xywh2cs(*obj['clean_bbox'][:4]) - scale = scale * 1.25 + image_file = os.path.join(self.img_prefix, self.id2name[index]) + rec.append({ + 'image_file': image_file, + 'center': center, + 'scale': scale, + 'rotation': 0, + 'joints_3d': joints_3d, + 'joints_3d_visible': joints_3d_visible, + 'dataset': 'aic', + 'bbox_score': 1 + }) - return center, scale + return rec def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): """Evaluate coco keypoint results. The pose prediction results will be @@ -277,7 +223,7 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): kpts = defaultdict(list) for preds, boxes, image_path in outputs: str_image_path = ''.join(image_path) - image_id = self.name2id(str_image_path) + image_id = self.name2id[os.path.basename(str_image_path)] kpts[image_id].append({ 'keypoints': preds[0], @@ -328,50 +274,6 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): return name_value - def _write_coco_keypoint_results(self, keypoints, res_file): - """Write results into a json file.""" - data_pack = [{ - 'cat_id': self._class_to_coco_ind[cls], - 'cls_ind': cls_ind, - 'cls': cls, - 'ann_type': 'keypoints', - 'keypoints': keypoints - } for cls_ind, cls in enumerate(self.classes) - if not cls == '__background__'] - - results = self._coco_keypoint_results_one_category_kernel(data_pack[0]) - - with open(res_file, 'w') as f: - json.dump(results, f, sort_keys=True, indent=4) - - def _coco_keypoint_results_one_category_kernel(self, data_pack): - """Get coco keypoint results.""" - cat_id = data_pack['cat_id'] - keypoints = data_pack['keypoints'] - cat_results = [] - - for img_kpts in keypoints: - if len(img_kpts) == 0: - continue - - _key_points = np.array( - [img_kpt['keypoints'] for img_kpt in img_kpts]) - key_points = _key_points.reshape(-1, - self.ann_info['num_joints'] * 3) - - result = [{ - 'image_id': img_kpt['image_id'], - 'category_id': cat_id, - 'keypoints': list(key_point), - 'score': img_kpt['score'], - 'center': list(img_kpt['center']), - 'scale': list(img_kpt['scale']) - } for img_kpt, key_point in zip(img_kpts, key_points)] - - cat_results.extend(result) - - return cat_results - def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" From 11aa71f291e3b78af6efc9cb2377c88ed88bc002 Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 18:52:57 +0800 Subject: [PATCH 08/25] use gt_bbox --- configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py | 2 +- configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py | 2 +- configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py | 2 +- configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py | 2 +- configs/top_down/resnet/aic/res101_aic_256x192.py | 2 +- configs/top_down/resnet/aic/res101_aic_384x288.py | 2 +- configs/top_down/resnet/aic/res152_aic_256x192.py | 2 +- configs/top_down/resnet/aic/res152_aic_384x288.py | 2 +- configs/top_down/resnet/aic/res50_aic_384x288.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py index 99ec61652a..97a1903e48 100644 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py @@ -95,7 +95,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/coco/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py index 3d5c9f9e74..764780bce1 100755 --- a/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w32_aic_384x288.py @@ -95,7 +95,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py index b74106b722..21cd4e77fa 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_256x192.py @@ -95,7 +95,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py index f20a96649f..652bc02963 100755 --- a/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py +++ b/configs/top_down/hrnet/aic/hrnet_w48_aic_384x288.py @@ -96,7 +96,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/resnet/aic/res101_aic_256x192.py b/configs/top_down/resnet/aic/res101_aic_256x192.py index a316815d30..53f5d7ad78 100755 --- a/configs/top_down/resnet/aic/res101_aic_256x192.py +++ b/configs/top_down/resnet/aic/res101_aic_256x192.py @@ -65,7 +65,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/resnet/aic/res101_aic_384x288.py b/configs/top_down/resnet/aic/res101_aic_384x288.py index 9853fbae72..901df1fa0a 100755 --- a/configs/top_down/resnet/aic/res101_aic_384x288.py +++ b/configs/top_down/resnet/aic/res101_aic_384x288.py @@ -65,7 +65,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/resnet/aic/res152_aic_256x192.py b/configs/top_down/resnet/aic/res152_aic_256x192.py index e7046303b2..e99e99e8d1 100755 --- a/configs/top_down/resnet/aic/res152_aic_256x192.py +++ b/configs/top_down/resnet/aic/res152_aic_256x192.py @@ -65,7 +65,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/resnet/aic/res152_aic_384x288.py b/configs/top_down/resnet/aic/res152_aic_384x288.py index aed9d4a8cc..04dd5e0548 100755 --- a/configs/top_down/resnet/aic/res152_aic_384x288.py +++ b/configs/top_down/resnet/aic/res152_aic_384x288.py @@ -65,7 +65,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', diff --git a/configs/top_down/resnet/aic/res50_aic_384x288.py b/configs/top_down/resnet/aic/res50_aic_384x288.py index e6affae2ac..da36ead9f9 100755 --- a/configs/top_down/resnet/aic/res50_aic_384x288.py +++ b/configs/top_down/resnet/aic/res50_aic_384x288.py @@ -65,7 +65,7 @@ oks_thr=0.9, vis_thr=0.2, bbox_thr=1.0, - use_gt_bbox=False, + use_gt_bbox=True, image_thr=0.0, bbox_file='data/person_detection_results/' 'COCO_val2017_detections_AP_H_56_person.json', From 16755e7525d0518bafa70125871d0eb4c1f4b796 Mon Sep 17 00:00:00 2001 From: jin-s13 Date: Wed, 12 Aug 2020 19:51:14 +0800 Subject: [PATCH 09/25] fix typo --- mmpose/datasets/datasets/top_down/topdown_aic_dataset.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 443e99e737..983bcd63d1 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -151,7 +151,7 @@ def _load_coco_keypoint_annotation_kernel(self, index): height = im_ann['height'] num_joints = self.ann_info['num_joints'] - ann_ids = self.coco.getAnnIds(imgIds=index, iscrowd=False) + ann_ids = self.coco.getAnnIds(imgIds=index) objs = self.coco.loadAnns(ann_ids) # sanitize bboxes @@ -162,7 +162,8 @@ def _load_coco_keypoint_annotation_kernel(self, index): y1 = max(0, y) x2 = min(width - 1, x1 + max(0, w - 1)) y2 = min(height - 1, y1 + max(0, h - 1)) - if obj['area'] > 0 and x2 >= x1 and y2 >= y1: + if ('area' not in obj + or obj['area'] > 0) and x2 >= x1 and y2 >= y1: obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1] valid_objs.append(obj) objs = valid_objs From cf2a92b067e519f760d7d29ec6e46e0d35e6c994 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Tue, 18 Aug 2020 21:58:38 +0800 Subject: [PATCH 10/25] lint --- mmpose/datasets/datasets/__init__.py | 6 +++--- mmpose/datasets/datasets/top_down/__init__.py | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mmpose/datasets/datasets/__init__.py b/mmpose/datasets/datasets/__init__.py index 735ea64d52..06367772f1 100644 --- a/mmpose/datasets/datasets/__init__.py +++ b/mmpose/datasets/datasets/__init__.py @@ -1,7 +1,7 @@ from .bottom_up import BottomUpCocoDataset -from .top_down import (TopDownCocoDataset, TopDownMpiiDataset, - TopDownMpiiTrbDataset, TopDownOCHumanDataset, - TopDownOneHand10KDataset, TopDownAicDataset) +from .top_down import (TopDownAicDataset, TopDownCocoDataset, + TopDownMpiiDataset, TopDownMpiiTrbDataset, + TopDownOCHumanDataset, TopDownOneHand10KDataset) __all__ = [ 'TopDownCocoDataset', 'BottomUpCocoDataset', 'TopDownMpiiDataset', diff --git a/mmpose/datasets/datasets/top_down/__init__.py b/mmpose/datasets/datasets/top_down/__init__.py index f408c0b3dd..69ca4e30e9 100644 --- a/mmpose/datasets/datasets/top_down/__init__.py +++ b/mmpose/datasets/datasets/top_down/__init__.py @@ -5,8 +5,7 @@ from .topdown_ochuman_dataset import TopDownOCHumanDataset from .topdown_onehand10k_dataset import TopDownOneHand10KDataset - __all__ = [ 'TopDownCocoDataset', 'TopDownMpiiTrbDataset', 'TopDownMpiiDataset', 'TopDownOneHand10KDataset', 'TopDownOCHumanDataset', 'TopDownAicDataset' -] \ No newline at end of file +] From ebf2efd01ff9777831240e82804a1c7df402fe07 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 19 Aug 2020 10:25:54 +0800 Subject: [PATCH 11/25] add sigma --- .../datasets/top_down/topdown_aic_dataset.py | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 983bcd63d1..6336862b26 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -109,6 +109,12 @@ def __init__(self, ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) + self.sigmas = np.array([ + 0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, + 0.01402144, 0.03909642, 0.03686941, 0.01981803, 0.03843971, + 0.03412318, 0.02415081, 0.01291456, 0.01236173 + ]) + self.coco = COCO(test_num_keypoints=14, annotation_file=ann_file) cats = [ @@ -258,10 +264,13 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): if self.soft_nms: keep = soft_oks_nms( - [img_kpts[i] for i in range(len(img_kpts))], oks_thr) + [img_kpts[i] for i in range(len(img_kpts))], + oks_thr, + sigmas=self.sigmas) else: keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))], - oks_thr) + oks_thr, + sigmas=self.sigmas) if len(keep) == 0: oks_nmsed_kpts.append(img_kpts) @@ -278,13 +287,8 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" - sigmas = np.array([ - 0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, - 0.01402144, 0.03909642, 0.03686941, 0.01981803, 0.03843971, - 0.03412318, 0.02415081, 0.01291456, 0.01236173 - ]) coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(sigmas, self.coco, coco_dt, 'keypoints') + coco_eval = COCOeval(self.sigmas, self.coco, coco_dt, 'keypoints') coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() From 34ceb56b8ec5dc86246b49630116dcfa6f3b7510 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 19 Aug 2020 14:39:35 +0800 Subject: [PATCH 12/25] update cocoeval --- mmpose/datasets/datasets/top_down/topdown_aic_dataset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 6336862b26..e268c611f3 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -288,7 +288,8 @@ def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(self.sigmas, self.coco, coco_dt, 'keypoints') + coco_eval = COCOeval( + self.sigmas, self.coco, coco_dt, 'keypoints', use_area=False) coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() From 8c31a0447652a5cb64dfa1028e4eaee493b30d99 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Fri, 21 Aug 2020 00:06:56 +0800 Subject: [PATCH 13/25] use xtcocotools --- .../datasets/top_down/topdown_aic_dataset.py | 25 ++++--------------- setup.cfg | 2 +- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index e268c611f3..9123693e90 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -2,8 +2,8 @@ from collections import OrderedDict, defaultdict import numpy as np -from pycocotools.coco import COCO -from pycocotools.cocoeval import COCOeval +from xtcocotools.coco import COCO +from xtcocotools.cocoeval import COCOeval from ....core.post_processing import oks_nms, soft_oks_nms from ...registry import DATASETS @@ -91,22 +91,7 @@ def __init__(self, self.ann_info['use_different_joint_weights'] = False self.ann_info['joint_weights'] = np.array( - [ - 1., - 1.2, - 1.5, - 1., - 1.2, - 1.5, - 1., - 1.2, - 1.5, - 1., - 1.2, - 1.5, - 1., - 1., - ], + [1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.], dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) self.sigmas = np.array([ @@ -115,7 +100,7 @@ def __init__(self, 0.03412318, 0.02415081, 0.01291456, 0.01236173 ]) - self.coco = COCO(test_num_keypoints=14, annotation_file=ann_file) + self.coco = COCO(ann_file) cats = [ cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds()) @@ -289,7 +274,7 @@ def _do_python_keypoint_eval(self, res_file): coco_dt = self.coco.loadRes(res_file) coco_eval = COCOeval( - self.sigmas, self.coco, coco_dt, 'keypoints', use_area=False) + self.coco, coco_dt, 'keypoints', self.sigmas, use_area=False) coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() diff --git a/setup.cfg b/setup.cfg index b667e81520..6d549cedce 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,6 +17,6 @@ line_length = 79 multi_line_output = 0 known_standard_library = pkg_resources,setuptools known_first_party = mmpose -known_third_party = cv2,json_tricks,mmcv,mmdet,munkres,numpy,pycocotools,pytest,scipy,torch,torchvision +known_third_party = cv2,json_tricks,mmcv,mmdet,munkres,numpy,pycocotools,pytest,scipy,torch,torchvision,xtcocotools no_lines_before = STDLIB,LOCALFOLDER default_section = THIRDPARTY From bddcbca2f4717fa0f2d203a9af27de6ee6602782 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Sat, 22 Aug 2020 20:14:01 +0800 Subject: [PATCH 14/25] fix sigmas --- mmpose/datasets/datasets/top_down/topdown_aic_dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 9123693e90..a420255ea9 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -98,7 +98,7 @@ def __init__(self, 0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, 0.01402144, 0.03909642, 0.03686941, 0.01981803, 0.03843971, 0.03412318, 0.02415081, 0.01291456, 0.01236173 - ]) + ]) * 2 self.coco = COCO(ann_file) From 0122bc17ef55fd5c3d0b9511e0417fa551c0c78d Mon Sep 17 00:00:00 2001 From: jinsheng Date: Tue, 25 Aug 2020 22:44:55 +0800 Subject: [PATCH 15/25] add xtcocotools --- requirements/runtime.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements/runtime.txt b/requirements/runtime.txt index c86ea7cca7..209d33028e 100644 --- a/requirements/runtime.txt +++ b/requirements/runtime.txt @@ -7,3 +7,4 @@ opencv-python pillow pycocotools scipy +xtcocotools From 6c87af358c8423e9e0664a7eb24989e5e865e465 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 26 Aug 2020 13:19:30 +0800 Subject: [PATCH 16/25] add aic tests --- mmpose/datasets/__init__.py | 11 +- ...4d9ce9201beffc76e5ff2169d2af2f027002ca.jpg | Bin 0 -> 61314 bytes ...436c914fe4a8ec1ec5474af4d3820b84d17561.jpg | Bin 0 -> 95597 bytes ...945ae2e729f24eea992814639d59b3bdec8bd8.jpg | Bin 0 -> 89897 bytes tests/data/aic/test_aic.json | 625 ++++++++++++++++++ tests/test_datasets/test_top_down_dataset.py | 66 ++ 6 files changed, 697 insertions(+), 5 deletions(-) create mode 100644 tests/data/aic/054d9ce9201beffc76e5ff2169d2af2f027002ca.jpg create mode 100644 tests/data/aic/fa436c914fe4a8ec1ec5474af4d3820b84d17561.jpg create mode 100644 tests/data/aic/ff945ae2e729f24eea992814639d59b3bdec8bd8.jpg create mode 100644 tests/data/aic/test_aic.json diff --git a/mmpose/datasets/__init__.py b/mmpose/datasets/__init__.py index aba648c7d1..041c22cd6b 100644 --- a/mmpose/datasets/__init__.py +++ b/mmpose/datasets/__init__.py @@ -1,7 +1,8 @@ from .builder import build_dataloader, build_dataset -from .datasets import (BottomUpCocoDataset, TopDownCocoDataset, - TopDownMpiiDataset, TopDownMpiiTrbDataset, - TopDownOCHumanDataset, TopDownOneHand10KDataset) +from .datasets import (BottomUpCocoDataset, TopDownAicDataset, + TopDownCocoDataset, TopDownMpiiDataset, + TopDownMpiiTrbDataset, TopDownOCHumanDataset, + TopDownOneHand10KDataset) from .pipelines import Compose from .registry import DATASETS, PIPELINES from .samplers import DistributedSampler @@ -9,6 +10,6 @@ __all__ = [ 'TopDownCocoDataset', 'BottomUpCocoDataset', 'TopDownMpiiTrbDataset', 'TopDownOneHand10KDataset', 'TopDownMpiiDataset', 'TopDownOCHumanDataset', - 'build_dataloader', 'build_dataset', 'Compose', 'DistributedSampler', - 'DATASETS', 'PIPELINES' + 'TopDownAicDataset', 'build_dataloader', 'build_dataset', 'Compose', + 'DistributedSampler', 'DATASETS', 'PIPELINES' ] diff --git a/tests/data/aic/054d9ce9201beffc76e5ff2169d2af2f027002ca.jpg b/tests/data/aic/054d9ce9201beffc76e5ff2169d2af2f027002ca.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8a569449d61984ad26cf13897adb718067de1406 GIT binary patch literal 61314 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 z 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 literal 0 HcmV?d00001 diff --git a/tests/data/aic/test_aic.json b/tests/data/aic/test_aic.json new file mode 100644 index 0000000000..28b006a5ff --- /dev/null +++ b/tests/data/aic/test_aic.json @@ -0,0 +1,625 @@ +{ + "info": { + "description": "MMPose example aic dataset", + "version": "1.0", + "year": "2020", + "date_created": "2020/08/25" + }, + "licenses": [ + { + "url": "", + "id": 1, + "name": "" + } + ], + "categories": [ + { + "supercategory": "person", + "id": 1, + "name": "person", + "keypoints": [ + "Right Shoulder", + "Right Elbow", + "Right Wrist", + "Left Shoulder", + "Left Elbow", + "Left Wrist", + "Right Hip", + "Right Knee", + "Right Ankle", + "Left Hip", + "Left Knee", + "Left Ankle", + "Head top", + "Neck" + ], + "skeleton": [ + [ + 3, + 2 + ], + [ + 2, + 1 + ], + [ + 1, + 14 + ], + [ + 14, + 4 + ], + [ + 4, + 5 + ], + [ + 5, + 6 + ], + [ + 9, + 8 + ], + [ + 8, + 7 + ], + [ + 7, + 10 + ], + [ + 10, + 11 + ], + [ + 11, + 12 + ], + [ + 13, + 14 + ], + [ + 1, + 7 + ], + [ + 4, + 10 + ] + ] + } + ], + "images": [ + { + "url": "http://www.sinaimg.cn/dy/slidenews/4_img/2013_47/704_1154733_789201.jpg", + "file_name": "054d9ce9201beffc76e5ff2169d2af2f027002ca.jpg", + "height": 600, + "width": 900, + "id": 1 + }, + { + "url": "http://www.sinaimg.cn/dy/slidenews/2_img/2015_26/820_1533617_599302.jpg", + "file_name": "fa436c914fe4a8ec1ec5474af4d3820b84d17561.jpg", + "height": 596, + "width": 900, + "id": 2 + }, + { + "url": "http://www.sinaimg.cn/dy/slidenews/2_img/2016_39/730_1947359_260964.jpg", + "file_name": "ff945ae2e729f24eea992814639d59b3bdec8bd8.jpg", + "height": 641, + "width": 950, + "id": 3 + } + ], + "annotations": [ + { + "bbox": [ + 279, + 55, + 213, + 544 + ], + "keypoints": [ + 313, + 201, + 2, + 312, + 313, + 1, + 320, + 424, + 2, + 406, + 197, + 1, + 431, + 286, + 1, + 459, + 269, + 2, + 375, + 447, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 416, + 441, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 395, + 74, + 2, + 372, + 170, + 2 + ], + "num_keypoints": 10, + "image_id": 1, + "category_id": 1, + "id": 4 + }, + { + "bbox": [ + 541, + 131, + 329, + 468 + ], + "keypoints": [ + 637, + 374, + 1, + 626, + 509, + 2, + 0, + 0, + 0, + 755, + 347, + 2, + 728, + 538, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 604, + 169, + 2, + 674, + 290, + 2 + ], + "num_keypoints": 6, + "image_id": 1, + "category_id": 1, + "id": 5 + }, + { + "bbox": [ + 88, + 7, + 252, + 592 + ], + "keypoints": [ + 144, + 180, + 2, + 171, + 325, + 1, + 256, + 428, + 1, + 265, + 196, + 2, + 297, + 311, + 2, + 300, + 412, + 2, + 178, + 476, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 253, + 474, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 220, + 23, + 2, + 205, + 133, + 2 + ], + "num_keypoints": 10, + "image_id": 1, + "category_id": 1, + "id": 6 + }, + { + "bbox": [ + 497, + 179, + 401, + 416 + ], + "keypoints": [ + 692, + 332, + 1, + 587, + 430, + 2, + 612, + 552, + 1, + 657, + 422, + 2, + 533, + 571, + 2, + 621, + 450, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 564, + 212, + 2, + 656, + 362, + 2 + ], + "num_keypoints": 8, + "image_id": 2, + "category_id": 1, + "id": 7 + }, + { + "bbox": [ + 336, + 26, + 177, + 254 + ], + "keypoints": [ + 368, + 142, + 2, + 365, + 237, + 1, + 415, + 271, + 1, + 487, + 147, + 2, + 493, + 240, + 2, + 431, + 265, + 2, + 393, + 296, + 1, + 326, + 306, + 1, + 339, + 390, + 1, + 449, + 297, + 1, + 373, + 315, + 1, + 376, + 389, + 1, + 435, + 43, + 2, + 430, + 131, + 2 + ], + "num_keypoints": 14, + "image_id": 2, + "category_id": 1, + "id": 8 + }, + { + "bbox": [ + 0, + 109, + 473, + 486 + ], + "keypoints": [ + 68, + 333, + 2, + 215, + 408, + 2, + 376, + 427, + 2, + 169, + 280, + 1, + 166, + 386, + 1, + 146, + 462, + 2, + 39, + 545, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 136, + 515, + 1, + 292, + 531, + 1, + 0, + 0, + 0, + 181, + 147, + 2, + 127, + 269, + 2 + ], + "num_keypoints": 11, + "image_id": 2, + "category_id": 1, + "id": 9 + }, + { + "bbox": [ + 681, + 3, + 267, + 607 + ], + "keypoints": [ + 846, + 98, + 1, + 862, + 223, + 1, + 794, + 282, + 2, + 824, + 134, + 2, + 875, + 241, + 2, + 842, + 329, + 2, + 903, + 296, + 1, + 766, + 397, + 1, + 777, + 562, + 2, + 886, + 299, + 2, + 757, + 399, + 2, + 871, + 514, + 2, + 761, + 29, + 2, + 813, + 87, + 2 + ], + "num_keypoints": 14, + "image_id": 3, + "category_id": 1, + "id": 10 + }, + { + "bbox": [ + 484, + 7, + 162, + 481 + ], + "keypoints": [ + 544, + 96, + 2, + 506, + 161, + 2, + 542, + 208, + 2, + 606, + 93, + 2, + 615, + 151, + 1, + 622, + 187, + 2, + 571, + 251, + 2, + 553, + 361, + 2, + 556, + 458, + 2, + 591, + 251, + 1, + 581, + 363, + 2, + 587, + 456, + 2, + 587, + 21, + 2, + 578, + 80, + 2 + ], + "num_keypoints": 14, + "image_id": 3, + "category_id": 1, + "id": 11 + }, + { + "bbox": [ + 33, + 73, + 493, + 566 + ], + "keypoints": [ + 254, + 203, + 2, + 169, + 203, + 2, + 111, + 187, + 2, + 391, + 204, + 2, + 425, + 276, + 2, + 475, + 346, + 2, + 272, + 376, + 2, + 185, + 485, + 2, + 126, + 607, + 1, + 357, + 383, + 2, + 359, + 459, + 2, + 350, + 561, + 2, + 338, + 111, + 2, + 325, + 180, + 1 + ], + "num_keypoints": 14, + "image_id": 3, + "category_id": 1, + "id": 12 + } + ] +} diff --git a/tests/test_datasets/test_top_down_dataset.py b/tests/test_datasets/test_top_down_dataset.py index 68de0c170e..16629cece4 100644 --- a/tests/test_datasets/test_top_down_dataset.py +++ b/tests/test_datasets/test_top_down_dataset.py @@ -1,6 +1,8 @@ import copy from unittest.mock import MagicMock +import pytest + from mmpose.datasets import DATASETS @@ -186,3 +188,67 @@ def test_top_down_MPII_TRB_dataset(): test_mode=True) assert custom_dataset.test_mode is True + + +def test_top_down_AIC_dataset(): + dataset = 'TopDownAicDataset' + # test AIC datasets + dataset_class = DATASETS.get(dataset) + dataset_class.load_annotations = MagicMock() + dataset_class.coco = MagicMock() + + channel_cfg = dict( + num_output_channels=14, + dataset_joints=14, + dataset_channel=[ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + ], + inference_channel=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]) + + data_cfg = dict( + image_size=[192, 256], + heatmap_size=[48, 64], + num_output_channels=channel_cfg['num_output_channels'], + num_joints=channel_cfg['dataset_joints'], + dataset_channel=channel_cfg['dataset_channel'], + inference_channel=channel_cfg['inference_channel'], + soft_nms=False, + nms_thr=1.0, + oks_thr=0.9, + vis_thr=0.2, + bbox_thr=1.0, + use_gt_bbox=True, + image_thr=0.0, + bbox_file='') + + with pytest.raises(AssertionError): + # Test det bbox + data_cfg_copy = copy.deepcopy(data_cfg) + data_cfg_copy['use_gt_bbox'] = False + _ = dataset_class( + ann_file='tests/data/aic/test_aic.json', + img_prefix='tests/data/aic/', + data_cfg=data_cfg_copy, + pipeline=[], + test_mode=True) + + _ = dataset_class( + ann_file='tests/data/aic/test_aic.json', + img_prefix='tests/data/aic/', + data_cfg=data_cfg_copy, + pipeline=[], + test_mode=False) + + # Test gt bbox + custom_dataset = dataset_class( + ann_file='tests/data/aic/test_aic.json', + img_prefix='tests/data/aic/', + data_cfg=data_cfg, + pipeline=[], + test_mode=True) + + assert custom_dataset.test_mode is True + + image_id = 1 + assert image_id in custom_dataset.image_set_index + assert len(custom_dataset.image_set_index) == 3 From 1388bd594b8161c79f0feacc47289ec53bcce41a Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 26 Aug 2020 19:57:04 +0800 Subject: [PATCH 17/25] add modelzoo and data_prepare --- configs/top_down/hrnet/README.md | 7 ++ configs/top_down/resnet/README.md | 6 + docs/data_preparation.md | 198 ++++++++++++++++++++++++++++++ docs/getting_started.md | 143 ++------------------- 4 files changed, 221 insertions(+), 133 deletions(-) create mode 100644 docs/data_preparation.md diff --git a/configs/top_down/hrnet/README.md b/configs/top_down/hrnet/README.md index f52d03547a..7dc416b17e 100644 --- a/configs/top_down/hrnet/README.md +++ b/configs/top_down/hrnet/README.md @@ -23,6 +23,13 @@ | [pose_hrnet_w48](/configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py) | 384x288 | 0.767 | 0.910 | 0.831 | 0.816 | 0.946 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288-314c8528_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_20200708.log.json) | +### Results on AIC val set. + +| Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | +| :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | +| [pose_hrnet_w32](/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py) | 256x192 | 0.675 | 0.957 | 0.751 | 0.703 | 0.961 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192-30a4e465_20200826.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192_20200826.log.json) | + + ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | diff --git a/configs/top_down/resnet/README.md b/configs/top_down/resnet/README.md index 9e4b3f27a3..b01c1b67a3 100644 --- a/configs/top_down/resnet/README.md +++ b/configs/top_down/resnet/README.md @@ -40,6 +40,12 @@ Following the common setting, the models are trained on COCO train dataset, and | [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_384x288.py) | 384x288 | 0.582 | 0.723 | 0.627 | 0.627 | 0.752 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | +### Results on AIC val set. + +| Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | +| :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | +| [pose_resnet_101](/configs/top_down/resnet/aic/res101_aic_256x192.py) | 256x192 | 0.650 | 0.947 | 0.726 | 0.680 | 0.954 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192-79b35445_20200826.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192_20200826.log.json) | + ### Results on MPII val set. diff --git a/docs/data_preparation.md b/docs/data_preparation.md new file mode 100644 index 0000000000..afe8aa5d21 --- /dev/null +++ b/docs/data_preparation.md @@ -0,0 +1,198 @@ +# Prepare datasets + +It is recommended to symlink the dataset root to `$MMPOSE/data`. +If your folder structure is different, you may need to change the corresponding paths in config files. + +MMPose supported datasets: +- [x] [COCO](http://cocodataset.org/) +- [x] [MPII](http://human-pose.mpi-inf.mpg.de/) +- [x] [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) +- [x] [AI Challenger](https://github.com/AIChallenger/AI_Challenger_2017) +- [x] [OCHuman](https://github.com/liruilong940607/OCHumanApi) +- [x] [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) +- [x] [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) + + +**For COCO data**, please download from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation. [HRNet-Human-Pose-Estimation](https://github.com/HRNet/HRNet-Human-Pose-Estimation) provides person detection result of COCO val2017 to reproduce our multi-person pose estimation results. Please download from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) +Download and extract them under $MMPOSE/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── coco + │-- annotations + │ │-- person_keypoints_train2017.json + │ |-- person_keypoints_val2017.json + |-- person_detection_results + | |-- COCO_val2017_detections_AP_H_56_person.json + │-- train2017 + │ │-- 000000000009.jpg + │ │-- 000000000025.jpg + │ │-- 000000000030.jpg + │ │-- ... + `-- val2017 + │-- 000000000139.jpg + │-- 000000000285.jpg + │-- 000000000632.jpg + │-- ... + +``` + +**For MPII data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). +We have converted the original annotation files into json format, please download them from [mpii_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_annotations.tar). +Extract them under {MMPose}/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── mpii + |── annotations + | |── mpii_gt_val.mat + | |── mpii_test.json + | |── mpii_train.json + | |── mpii_trainval.json + | `── mpii_val.json + `── images + |── 000001163.jpg + |── 000003072.jpg + +``` + +**For MPII-TRB data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). +Please download the annotation files from [mpii_trb_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_trb_annotations.tar). +Extract them under {MMPose}/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── mpii + |── annotations + | |── mpii_trb_train.json + | |── mpii_trb_val.json + `── images + |── 000001163.jpg + |── 000003072.jpg + +``` + +**For AIC data**, please download from [AI Challenger 2017](https://github.com/AIChallenger/AI_Challenger_2017), 2017 Train/Val is needed for keypoints training and validation. +Please download the annotation files from [aic_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/aic_annotations.tar). +Download and extract them under $MMPOSE/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── aic + │-- annotations + │ │-- aic_train.json + │ |-- aic_val.json + │-- ai_challenger_keypoint_train_20170902 + │ │-- keypoint_train_images_20170902 + │ │ │-- 0000252aea98840a550dac9a78c476ecb9f47ffa.jpg + │ │ │-- 000050f770985ac9653198495ef9b5c82435d49c.jpg + │ │ │-- ... + `-- ai_challenger_keypoint_validation_20170911 + │-- keypoint_validation_images_20170911 + │-- 0002605c53fb92109a3f2de4fc3ce06425c3b61f.jpg + │-- 0003b55a2c991223e6d8b4b820045bd49507bf6d.jpg + │-- ... +``` + +**For CrowdPose data**, please download from [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose). +Please download the annotation files from [crowdpose_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/aic_annotations.tar). +We follow [CrowdPose](https://arxiv.org/abs/1812.00324) to use the [pre-trained weights](https://pjreddie.com/media/files/yolov3.weights) of [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) to generate the detected human bounding boxes. +Download and extract them under $MMPOSE/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── crowdpose + │-- annotations + │ │-- mmpose_crowdpose_train.json + │ │-- mmpose_crowdpose_val.json + │ │-- mmpose_crowdpose_test.json + │ │-- det_for_crowd_test_0.1_0.5.json + │-- images + │-- 100000.jpg + │-- 100001.jpg + │-- 100002.jpg + │-- ... +``` + +**For OCHuman data**, please download the images and annotations from [OCHuman](https://github.com/liruilong940607/OCHumanApi), +Move them under $MMPOSE/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── ochuman + │-- annotations + │ │-- ochuman_coco_format_val_range_0.00_1.00.json + │ |-- ochuman_coco_format_test_range_0.00_1.00.json + |-- images + │-- 000001.jpg + │-- 000002.jpg + │-- 000003.jpg + │-- ... + +``` + +**For OneHand10K data**, please download from [OneHand10K Dataset](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html). +Please download the annotation files from [onehand10k_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/onehand10k_annotations.tar). +Extract them under {MMPose}/data, and make them look like this: + +``` +mmpose +├── mmpose +├── docs +├── tests +├── tools +├── configs +`── data + │── onehand10k + |── annotations + | |── onehand10k_train.json + | |── onehand10k_test.json + `── Train + | |── source + | |── 0.jpg + | |── 1.jpg + | ... + `── Test + |── source + |── 0.jpg + |── 1.jpg + +``` + +For using custom datasets, please refer to [Tutorial 2: Adding New Dataset](tutorials/new_dataset.md) diff --git a/docs/getting_started.md b/docs/getting_started.md index 8516570689..908bd60cb2 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -5,139 +5,16 @@ For installation instructions, please see [install.md](install.md). ## Prepare datasets -It is recommended to symlink the dataset root to `$MMPOSE/data`. -If your folder structure is different, you may need to change the corresponding paths in config files. - -**For COCO data**, please download from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation. [HRNet-Human-Pose-Estimation](https://github.com/HRNet/HRNet-Human-Pose-Estimation) provides person detection result of COCO val2017 to reproduce our multi-person pose estimation results. Please download from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) -Download and extract them under $MMPOSE/data, and make them look like this: - -``` -mmpose -├── mmpose -├── docs -├── tests -├── tools -├── configs -`── data - │── coco - │-- annotations - │ │-- person_keypoints_train2017.json - │ |-- person_keypoints_val2017.json - |-- person_detection_results - | |-- COCO_val2017_detections_AP_H_56_person.json - │-- train2017 - │ │-- 000000000009.jpg - │ │-- 000000000025.jpg - │ │-- 000000000030.jpg - │ │-- ... - `-- val2017 - │-- 000000000139.jpg - │-- 000000000285.jpg - │-- 000000000632.jpg - │-- ... - -``` - -**For MPII data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). -We have converted the original annotation files into json format, please download them from [mpii_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_annotations.tar). -Extract them under {MMPose}/data, and make them look like this: - -``` -mmpose -├── mmpose -├── docs -├── tests -├── tools -├── configs -`── data - │── mpii - |── annotations - | |── mpii_gt_val.mat - | |── mpii_test.json - | |── mpii_train.json - | |── mpii_trainval.json - | `── mpii_val.json - `── images - |── 000001163.jpg - |── 000003072.jpg - -``` - - -**For OCHuman data**, please download the images and annotations from [OCHuman](https://github.com/liruilong940607/OCHumanApi), -Move them under $MMPOSE/data, and make them look like this: - -``` -mmpose -├── mmpose -├── docs -├── tests -├── tools -├── configs -`── data - │── ochuman - │-- annotations - │ │-- ochuman_coco_format_val_range_0.00_1.00.json - │ |-- ochuman_coco_format_test_range_0.00_1.00.json - |-- images - │-- 000001.jpg - │-- 000002.jpg - │-- 000003.jpg - │-- ... - -``` - -**For MPII-TRB data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). -Please download the annotation files from [mpii_trb_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_trb_annotations.tar). -Extract them under {MMPose}/data, and make them look like this: - -``` -mmpose -├── mmpose -├── docs -├── tests -├── tools -├── configs -`── data - │── mpii - |── annotations - | |── mpii_trb_train.json - | |── mpii_trb_val.json - `── images - |── 000001163.jpg - |── 000003072.jpg - -``` - -**For OneHand10K data**, please download from [OneHand10K Dataset](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html). -Please download the annotation files from [onehand10k_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/onehand10k_annotations.tar). -Extract them under {MMPose}/data, and make them look like this: - -``` -mmpose -├── mmpose -├── docs -├── tests -├── tools -├── configs -`── data - │── onehand10k - |── annotations - | |── onehand10k_train.json - | |── onehand10k_test.json - `── Train - | |── source - | |── 0.jpg - | |── 1.jpg - | ... - `── Test - |── source - |── 0.jpg - |── 1.jpg - -``` - -For using custom datasets, please refer to [Tutorial 2: Adding New Dataset](tutorials/new_dataset.md) +MMPose supported datasets: +- [x] [COCO](http://cocodataset.org/) +- [x] [MPII](http://human-pose.mpi-inf.mpg.de/) +- [x] [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) +- [x] [AI Challenger](https://github.com/AIChallenger/AI_Challenger_2017) +- [x] [OCHuman](https://github.com/liruilong940607/OCHumanApi) +- [x] [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) +- [x] [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) + +Please follow [DATA Preparation](data_preparation.md) to prepare the data. ## Prepare Pretrained Models Download imagenet pretrained models from our [model zoo](model_zoo.md) From 92e1399129c3a3b1ec3090e32288ff3de251e4d9 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 26 Aug 2020 20:09:40 +0800 Subject: [PATCH 18/25] use accelerate links --- configs/bottom_up/higherhrnet/README.md | 12 ++--- configs/bottom_up/hrnet/README.md | 8 ++-- configs/bottom_up/mobilenet/README.md | 4 +- configs/bottom_up/resnet/README.md | 8 ++-- configs/top_down/alexnet/README.md | 2 +- configs/top_down/cpm/README.md | 2 +- configs/top_down/darkpose/README.md | 14 +++--- configs/top_down/hourglass/README.md | 8 ++-- configs/top_down/hrnet/README.md | 14 +++--- configs/top_down/mobilenet_v2/README.md | 6 +-- configs/top_down/resnet/README.md | 38 ++++++++-------- configs/top_down/resnetv1d/README.md | 18 ++++---- configs/top_down/resnext/README.md | 12 ++--- configs/top_down/scnet/README.md | 12 ++--- configs/top_down/seresnet/README.md | 12 ++--- configs/top_down/shufflenet_v1/README.md | 4 +- docs/data_preparation.md | 10 ++-- docs/model_zoo.md | 58 ++++++++++++------------ 18 files changed, 121 insertions(+), 121 deletions(-) diff --git a/configs/bottom_up/higherhrnet/README.md b/configs/bottom_up/higherhrnet/README.md index a6f1ee3738..249b275fc0 100644 --- a/configs/bottom_up/higherhrnet/README.md +++ b/configs/bottom_up/higherhrnet/README.md @@ -17,14 +17,14 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_512x512.py) | 512x512 | 0.677 | 0.870 | 0.738 | 0.723 | 0.890 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | -| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py) | 640x640 | 0.686 | 0.871 | 0.747 | 0.733 | 0.898 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | -| [HigherHRNet-w48](/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py) | 512x512 | 0.686 | 0.873 | 0.741 | 0.731 | 0.892 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | +| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_512x512.py) | 512x512 | 0.677 | 0.870 | 0.738 | 0.723 | 0.890 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | +| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py) | 640x640 | 0.686 | 0.871 | 0.747 | 0.733 | 0.898 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | +| [HigherHRNet-w48](/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py) | 512x512 | 0.686 | 0.873 | 0.741 | 0.731 | 0.892 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | ### Results on COCO val2017 with multi-scale test | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_512x512.py) | 512x512 | 0.706 | 0.881 | 0.771 | 0.747 | 0.901 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | -| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py) | 640x640 | 0.706 | 0.880 | 0.770 | 0.749 | 0.902 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | -| [HigherHRNet-w48](/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py) | 512x512 | 0.716 | 0.884 | 0.775 | 0.755 | 0.901 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | +| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_512x512.py) | 512x512 | 0.706 | 0.881 | 0.771 | 0.747 | 0.901 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | +| [HigherHRNet-w32](/configs/bottom_up/higherhrnet/coco/higher_hrnet32_coco_640x640.py) | 640x640 | 0.706 | 0.880 | 0.770 | 0.749 | 0.902 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | +| [HigherHRNet-w48](/configs/bottom_up/higherhrnet/coco/higher_hrnet48_coco_512x512.py) | 512x512 | 0.716 | 0.884 | 0.775 | 0.755 | 0.901 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | diff --git a/configs/bottom_up/hrnet/README.md b/configs/bottom_up/hrnet/README.md index 7a844590ac..6a5af1bae6 100644 --- a/configs/bottom_up/hrnet/README.md +++ b/configs/bottom_up/hrnet/README.md @@ -24,12 +24,12 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [HRNet-w32](/configs/bottom_up/hrnet/coco/hrnet_w32_coco_512x512.py) | 512x512 | 0.654 | 0.863 | 0.720 | 0.710 | 0.892 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | -| [HRNet-w48](/configs/bottom_up/hrnet/coco/hrnet_w48_coco_512x512.py) | 512x512 | 0.665 | 0.860 | 0.727 | 0.716 | 0.889 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512-cf72fcdf_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512_20200816.log.json) | +| [HRNet-w32](/configs/bottom_up/hrnet/coco/hrnet_w32_coco_512x512.py) | 512x512 | 0.654 | 0.863 | 0.720 | 0.710 | 0.892 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | +| [HRNet-w48](/configs/bottom_up/hrnet/coco/hrnet_w48_coco_512x512.py) | 512x512 | 0.665 | 0.860 | 0.727 | 0.716 | 0.889 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512-cf72fcdf_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512_20200816.log.json) | ### Results on COCO val2017 with multi-scale test with scales [2, 1, 0.5]. | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [HRNet-w32](/configs/bottom_up/hrnet/coco/hrnet_w32_coco_512x512.py) | 512x512 | 0.698 | 0.877 | 0.760 | 0.748 | 0.907 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | -| [HRNet-w48](/configs/bottom_up/hrnet/coco/hrnet_w48_coco_512x512.py) | 512x512 | 0.712 | 0.880 | 0.771 | 0.757 | 0.909 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512-cf72fcdf_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512_20200816.log.json) | +| [HRNet-w32](/configs/bottom_up/hrnet/coco/hrnet_w32_coco_512x512.py) | 512x512 | 0.698 | 0.877 | 0.760 | 0.748 | 0.907 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | +| [HRNet-w48](/configs/bottom_up/hrnet/coco/hrnet_w48_coco_512x512.py) | 512x512 | 0.712 | 0.880 | 0.771 | 0.757 | 0.909 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512-cf72fcdf_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w48_coco_512x512_20200816.log.json) | diff --git a/configs/bottom_up/mobilenet/README.md b/configs/bottom_up/mobilenet/README.md index d93f308da1..dcc0902182 100644 --- a/configs/bottom_up/mobilenet/README.md +++ b/configs/bottom_up/mobilenet/README.md @@ -24,10 +24,10 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_mobilenetv2](/configs/bottom_up/mobilenet/coco/mobilenetv2_coco_512x512.py) | 512x512 | 0.380 | 0.671 | 0.368 | 0.473 | 0.741 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/mobilenetv2_coco_512x512-4d96e309_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/mobilenetv2_coco_512x512_20200816.log.json) | +| [pose_mobilenetv2](/configs/bottom_up/mobilenet/coco/mobilenetv2_coco_512x512.py) | 512x512 | 0.380 | 0.671 | 0.368 | 0.473 | 0.741 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/mobilenetv2_coco_512x512-4d96e309_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/mobilenetv2_coco_512x512_20200816.log.json) | ### Results on COCO val2017 with multi-scale test with scales [2, 1, 0.5]. | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_mobilenetv2](/configs/bottom_up/mobilenet/coco/mobilenetv2_coco_512x512.py) | 512x512 | 0.442 | 0.696 | 0.422 | 0.517 | 0.766 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | +| [pose_mobilenetv2](/configs/bottom_up/mobilenet/coco/mobilenetv2_coco_512x512.py) | 512x512 | 0.442 | 0.696 | 0.422 | 0.517 | 0.766 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) | diff --git a/configs/bottom_up/resnet/README.md b/configs/bottom_up/resnet/README.md index b80e17aca2..1d0ed1b7c0 100644 --- a/configs/bottom_up/resnet/README.md +++ b/configs/bottom_up/resnet/README.md @@ -24,12 +24,12 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnet_50](/configs/bottom_up/resnet/coco/res50_coco_512x512.py) | 512x512 | 0.466 | 0.742 | 0.479 | 0.552 | 0.797 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512-5521bead_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512_20200816.log.json) | -| [pose_resnet_101](/configs/bottom_up/resnet/coco/res101_coco_512x512.py) | 512x512 | 0.554 | 0.807 | 0.599 | 0.622 | 0.841 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512-e0c95157_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512_20200816.log.json) | +| [pose_resnet_50](/configs/bottom_up/resnet/coco/res50_coco_512x512.py) | 512x512 | 0.466 | 0.742 | 0.479 | 0.552 | 0.797 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512-5521bead_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512_20200816.log.json) | +| [pose_resnet_101](/configs/bottom_up/resnet/coco/res101_coco_512x512.py) | 512x512 | 0.554 | 0.807 | 0.599 | 0.622 | 0.841 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512-e0c95157_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512_20200816.log.json) | ### Results on COCO val2017 with multi-scale test with scales [2, 1, 0.5]. | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnet_50](/configs/bottom_up/resnet/coco/res50_coco_512x512.py) | 512x512 | 0.503 | 0.765 | 0.521 | 0.591 | 0.821 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512-5521bead_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512_20200816.log.json) | -| [pose_resnet_101](/configs/bottom_up/resnet/coco/res101_coco_512x512.py) | 512x512 | 0.603 | 0.831 | 0.641 | 0.668 | 0.870 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512-e0c95157_20200816.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512_20200816.log.json) | +| [pose_resnet_50](/configs/bottom_up/resnet/coco/res50_coco_512x512.py) | 512x512 | 0.503 | 0.765 | 0.521 | 0.591 | 0.821 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512-5521bead_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res50_coco_512x512_20200816.log.json) | +| [pose_resnet_101](/configs/bottom_up/resnet/coco/res101_coco_512x512.py) | 512x512 | 0.603 | 0.831 | 0.641 | 0.668 | 0.870 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512-e0c95157_20200816.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/res101_coco_512x512_20200816.log.json) | diff --git a/configs/top_down/alexnet/README.md b/configs/top_down/alexnet/README.md index 9dc1273f3c..8c14647abc 100644 --- a/configs/top_down/alexnet/README.md +++ b/configs/top_down/alexnet/README.md @@ -17,4 +17,4 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_alexnet](/configs/top_down/alexnet/coco/alexnet_coco_256x192.py) | 256x192 | 0.397 | 0.758 | 0.381 | 0.478 | 0.822 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192-a243b840_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192_20200727.log.json) | +| [pose_alexnet](/configs/top_down/alexnet/coco/alexnet_coco_256x192.py) | 256x192 | 0.397 | 0.758 | 0.381 | 0.478 | 0.822 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192-a243b840_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192_20200727.log.json) | diff --git a/configs/top_down/cpm/README.md b/configs/top_down/cpm/README.md index 8ed46ef092..6b3182234f 100644 --- a/configs/top_down/cpm/README.md +++ b/configs/top_down/cpm/README.md @@ -17,4 +17,4 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [cpm](/configs/top_down/cpm/coco/cpm_coco_256x192.py) | 256x192 | 0.623 | 0.859 | 0.704 | 0.686 | 0.903 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/cpm/cpm_coco_256x192-aa4ba095_20200817.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/cpm/cpm_coco_256x192_20200817.log.json) | +| [cpm](/configs/top_down/cpm/coco/cpm_coco_256x192.py) | 256x192 | 0.623 | 0.859 | 0.704 | 0.686 | 0.903 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/cpm/cpm_coco_256x192-aa4ba095_20200817.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/cpm/cpm_coco_256x192_20200817.log.json) | diff --git a/configs/top_down/darkpose/README.md b/configs/top_down/darkpose/README.md index a50618501e..1ac6d70f80 100644 --- a/configs/top_down/darkpose/README.md +++ b/configs/top_down/darkpose/README.md @@ -17,10 +17,10 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [dark_pose_resnet_50](/configs/top_down/darkpose/coco/res50_coco_256x192_dark.py) | 256x192 | 0.724 | 0.898 | 0.800 | 0.777 | 0.936 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark-43379d20_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark_20200709.log.json) | -| [dark_pose_resnet_101](/configs/top_down/darkpose/coco/res101_coco_256x192_dark.py) | 256x192 | 0.732 | 0.899 | 0.808 | 0.786 | 0.938 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_dark-64d433e6_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_dark_20200812.log.json) | -| [dark_pose_resnet_152](/configs/top_down/darkpose/coco/res152_coco_256x192_dark.py) | 256x192 | 0.745 | 0.905 | 0.821 | 0.797 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_dark-ab4840d5_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_dark_20200812.log.json) | -| [dark_pose_hrnet_w32](/configs/top_down/darkpose/coco/hrnet_w32_coco_256x192_dark.py) | 256x192 | 0.757 | 0.907 | 0.823 | 0.808 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_dark-07f147eb_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_dark_20200812.log.json) | -| [dark_pose_hrnet_w32](/configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py) | 384x288 | 0.767 | 0.909 | 0.832 | 0.816 | 0.944 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_dark-459422a4_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_dark_20200812.log.json) | -| [dark_pose_hrnet_w48](/configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py) | 256x192 | 0.764 | 0.907 | 0.830 | 0.814 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_dark-8cba3197_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_dark_20200812.log.json) | -| [dark_pose_hrnet_w48](/configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py) | 384x288 | 0.773 | 0.910 | 0.833 | 0.820 | 0.946 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_dark-741844ba_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_dark_20200812.log.json) | +| [dark_pose_resnet_50](/configs/top_down/darkpose/coco/res50_coco_256x192_dark.py) | 256x192 | 0.724 | 0.898 | 0.800 | 0.777 | 0.936 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark-43379d20_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark_20200709.log.json) | +| [dark_pose_resnet_101](/configs/top_down/darkpose/coco/res101_coco_256x192_dark.py) | 256x192 | 0.732 | 0.899 | 0.808 | 0.786 | 0.938 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_dark-64d433e6_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_dark_20200812.log.json) | +| [dark_pose_resnet_152](/configs/top_down/darkpose/coco/res152_coco_256x192_dark.py) | 256x192 | 0.745 | 0.905 | 0.821 | 0.797 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_dark-ab4840d5_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_dark_20200812.log.json) | +| [dark_pose_hrnet_w32](/configs/top_down/darkpose/coco/hrnet_w32_coco_256x192_dark.py) | 256x192 | 0.757 | 0.907 | 0.823 | 0.808 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_dark-07f147eb_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_dark_20200812.log.json) | +| [dark_pose_hrnet_w32](/configs/top_down/darkpose/coco/hrnet_w32_coco_384x288_dark.py) | 384x288 | 0.767 | 0.909 | 0.832 | 0.816 | 0.944 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_dark-459422a4_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_dark_20200812.log.json) | +| [dark_pose_hrnet_w48](/configs/top_down/darkpose/coco/hrnet_w48_coco_256x192_dark.py) | 256x192 | 0.764 | 0.907 | 0.830 | 0.814 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_dark-8cba3197_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_dark_20200812.log.json) | +| [dark_pose_hrnet_w48](/configs/top_down/darkpose/coco/hrnet_w48_coco_384x288_dark.py) | 384x288 | 0.773 | 0.910 | 0.833 | 0.820 | 0.946 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_dark-741844ba_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_dark_20200812.log.json) | diff --git a/configs/top_down/hourglass/README.md b/configs/top_down/hourglass/README.md index 73c91baadf..4c8650c5d4 100644 --- a/configs/top_down/hourglass/README.md +++ b/configs/top_down/hourglass/README.md @@ -18,13 +18,13 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_hourglass_52](/configs/top_down/hourglass/coco/hourglass52_coco_256x256.py) | 256x256 | 0.726 | 0.896 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256_20200709.log.json) | -| [pose_hourglass_52](/configs/top_down/hourglass/coco/hourglass52_coco_384x384.py) | 384x384 | 0.746 | 0.900 | 0.813 | 0.797 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_384x384-be91ba2b_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_384x384_20200812.log.json) | +| [pose_hourglass_52](/configs/top_down/hourglass/coco/hourglass52_coco_256x256.py) | 256x256 | 0.726 | 0.896 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256_20200709.log.json) | +| [pose_hourglass_52](/configs/top_down/hourglass/coco/hourglass52_coco_384x384.py) | 384x384 | 0.746 | 0.900 | 0.813 | 0.797 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_384x384-be91ba2b_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_384x384_20200812.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_hourglass_52](/configs/top_down/hourglass/mpii/hourglass52_mpii_256x256.py) | 256x256 | 0.889 | 0.361 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256-ae358435_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256_20200812.log.json) | -| [pose_hourglass_52](/configs/top_down/hourglass/mpii/hourglass52_mpii_384x384.py) | 384x384 | 0.894 | 0.409 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384-04090bc3_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384_20200812.log.json) | +| [pose_hourglass_52](/configs/top_down/hourglass/mpii/hourglass52_mpii_256x256.py) | 256x256 | 0.889 | 0.361 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256-ae358435_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256_20200812.log.json) | +| [pose_hourglass_52](/configs/top_down/hourglass/mpii/hourglass52_mpii_384x384.py) | 384x384 | 0.894 | 0.409 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384-04090bc3_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384_20200812.log.json) | diff --git a/configs/top_down/hrnet/README.md b/configs/top_down/hrnet/README.md index 7dc416b17e..262d4ef179 100644 --- a/configs/top_down/hrnet/README.md +++ b/configs/top_down/hrnet/README.md @@ -17,22 +17,22 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_hrnet_w32](/configs/top_down/hrnet/coco/hrnet_w32_coco_256x192.py) | 256x192 | 0.746 | 0.904 | 0.819 | 0.799 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_20200708.log.json) | -| [pose_hrnet_w32](/configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py) | 384x288 | 0.760 | 0.906 | 0.829 | 0.810 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288-d9f0d786_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_20200708.log.json) | -| [pose_hrnet_w48](/configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py) | 256x192 | 0.756 | 0.907 | 0.825 | 0.806 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_20200708.log.json) | -| [pose_hrnet_w48](/configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py) | 384x288 | 0.767 | 0.910 | 0.831 | 0.816 | 0.946 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288-314c8528_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_20200708.log.json) | +| [pose_hrnet_w32](/configs/top_down/hrnet/coco/hrnet_w32_coco_256x192.py) | 256x192 | 0.746 | 0.904 | 0.819 | 0.799 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_20200708.log.json) | +| [pose_hrnet_w32](/configs/top_down/hrnet/coco/hrnet_w32_coco_384x288.py) | 384x288 | 0.760 | 0.906 | 0.829 | 0.810 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288-d9f0d786_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_20200708.log.json) | +| [pose_hrnet_w48](/configs/top_down/hrnet/coco/hrnet_w48_coco_256x192.py) | 256x192 | 0.756 | 0.907 | 0.825 | 0.806 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_20200708.log.json) | +| [pose_hrnet_w48](/configs/top_down/hrnet/coco/hrnet_w48_coco_384x288.py) | 384x288 | 0.767 | 0.910 | 0.831 | 0.816 | 0.946 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288-314c8528_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_20200708.log.json) | ### Results on AIC val set. | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_hrnet_w32](/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py) | 256x192 | 0.675 | 0.957 | 0.751 | 0.703 | 0.961 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192-30a4e465_20200826.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192_20200826.log.json) | +| [pose_hrnet_w32](/configs/top_down/hrnet/aic/hrnet_w32_aic_256x192.py) | 256x192 | 0.675 | 0.957 | 0.751 | 0.703 | 0.961 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192-30a4e465_20200826.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192_20200826.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_hrnet_w32](/configs/top_down/hourglass/mpii/hrnet_w32_mpii_256x256.py) | 256x256 | 0.900 | 0.379 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256-6c4f923f_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_20200812.log.json) | -| [pose_hrnet_w48](/configs/top_down/hourglass/mpii/hrnet_w48_mpii_256x256.py) | 256x256 | 0.900 | 0.383 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256-92cab7bd_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_20200812.log.json) | +| [pose_hrnet_w32](/configs/top_down/hourglass/mpii/hrnet_w32_mpii_256x256.py) | 256x256 | 0.900 | 0.379 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256-6c4f923f_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_20200812.log.json) | +| [pose_hrnet_w48](/configs/top_down/hourglass/mpii/hrnet_w48_mpii_256x256.py) | 256x256 | 0.900 | 0.383 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256-92cab7bd_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_20200812.log.json) | diff --git a/configs/top_down/mobilenet_v2/README.md b/configs/top_down/mobilenet_v2/README.md index d68fcbcf34..f9fbc30e93 100644 --- a/configs/top_down/mobilenet_v2/README.md +++ b/configs/top_down/mobilenet_v2/README.md @@ -17,11 +17,11 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py) | 256x192 | 0.646 | 0.874 | 0.723 | 0.707 | 0.917 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_256x192-d1e58e7b_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_256x192_20200727.log.json) | -| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py) | 384x288 | 0.673 | 0.879 | 0.743 | 0.729 | 0.916 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_384x288-26be4816_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_384x288_20200727.log.json) | +| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_256x192.py) | 256x192 | 0.646 | 0.874 | 0.723 | 0.707 | 0.917 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_256x192-d1e58e7b_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_256x192_20200727.log.json) | +| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/coco/mobilenetv2_coco_384x288.py) | 384x288 | 0.673 | 0.879 | 0.743 | 0.729 | 0.916 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_384x288-26be4816_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_coco_384x288_20200727.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/mpii/mobilenet_v2_mpii_256x256.py) | 256x256 | 0.854 | 0.272 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256-e068afa7_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256_20200812.log.json) | +| [pose_mobilenetv2](/configs/top_down/mobilenet_v2/mpii/mobilenet_v2_mpii_256x256.py) | 256x256 | 0.854 | 0.272 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256-e068afa7_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256_20200812.log.json) | diff --git a/configs/top_down/resnet/README.md b/configs/top_down/resnet/README.md index b01c1b67a3..5a6af0dd99 100644 --- a/configs/top_down/resnet/README.md +++ b/configs/top_down/resnet/README.md @@ -17,12 +17,12 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_256x192.py) | 256x192 | 0.718 | 0.898 | 0.795 | 0.773 | 0.937 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | -| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_384x288.py) | 384x288 | 0.731 | 0.900 | 0.799 | 0.783 | 0.931 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_256x192.py) | 256x192 | 0.726 | 0.899 | 0.806 | 0.781 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_384x288.py) | 384x288 | 0.748 | 0.905 | 0.817 | 0.798 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_256x192.py) | 256x192 | 0.735 | 0.905 | 0.812 | 0.790 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_384x288.py) | 384x288 | 0.750 | 0.908 | 0.821 | 0.800 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_256x192.py) | 256x192 | 0.718 | 0.898 | 0.795 | 0.773 | 0.937 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_384x288.py) | 384x288 | 0.731 | 0.900 | 0.799 | 0.783 | 0.931 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_256x192.py) | 256x192 | 0.726 | 0.899 | 0.806 | 0.781 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_384x288.py) | 384x288 | 0.748 | 0.905 | 0.817 | 0.798 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_256x192.py) | 256x192 | 0.735 | 0.905 | 0.812 | 0.790 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_384x288.py) | 384x288 | 0.750 | 0.908 | 0.821 | 0.800 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | @@ -32,34 +32,34 @@ Following the common setting, the models are trained on COCO train dataset, and | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_256x192.py) | 256x192 | 0.546 | 0.726 | 0.593 | 0.592 | 0.755 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | -| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_384x288.py) | 384x288 | 0.539 | 0.723 | 0.574 | 0.588 | 0.756 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_256x192.py) | 256x192 | 0.559 | 0.724 | 0.606 | 0.605 | 0.751 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_384x288.py) | 384x288 | 0.571 | 0.715 | 0.615 | 0.615 | 0.748 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_256x192.py) | 256x192 | 0.570 | 0.725 | 0.617 | 0.616 | 0.754 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_384x288.py) | 384x288 | 0.582 | 0.723 | 0.627 | 0.627 | 0.752 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_256x192.py) | 256x192 | 0.546 | 0.726 | 0.593 | 0.592 | 0.755 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/coco/res50_coco_384x288.py) | 384x288 | 0.539 | 0.723 | 0.574 | 0.588 | 0.756 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_256x192.py) | 256x192 | 0.559 | 0.724 | 0.606 | 0.605 | 0.751 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/coco/res101_coco_384x288.py) | 384x288 | 0.571 | 0.715 | 0.615 | 0.615 | 0.748 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_256x192.py) | 256x192 | 0.570 | 0.725 | 0.617 | 0.616 | 0.754 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/coco/res152_coco_384x288.py) | 384x288 | 0.582 | 0.723 | 0.627 | 0.627 | 0.752 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | ### Results on AIC val set. | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :-------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnet_101](/configs/top_down/resnet/aic/res101_aic_256x192.py) | 256x192 | 0.650 | 0.947 | 0.726 | 0.680 | 0.954 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192-79b35445_20200826.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192_20200826.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/aic/res101_aic_256x192.py) | 256x192 | 0.650 | 0.947 | 0.726 | 0.680 | 0.954 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192-79b35445_20200826.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_aic_256x192_20200826.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_resnet_50](/configs/top_down/resnet/mpii/res50_mpii_256x256.py) | 256x256 | 0.882 | 0.329 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_256x256_20200812.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/mpii/res101_mpii_256x256.py) | 256x256 | 0.887 | 0.333 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_256x256-416f5d71_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_256x256_20200812.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/mpii/res152_mpii_256x256.py) | 256x256 | 0.890 | 0.347 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_256x256-3ecba29d_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_256x256_20200812.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/mpii/res50_mpii_256x256.py) | 256x256 | 0.882 | 0.329 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_256x256_20200812.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/mpii/res101_mpii_256x256.py) | 256x256 | 0.887 | 0.333 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_256x256-416f5d71_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_256x256_20200812.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/mpii/res152_mpii_256x256.py) | 256x256 | 0.890 | 0.347 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_256x256-3ecba29d_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_256x256_20200812.log.json) | ### Results on MPII-TRB val set. | Arch | Input Size | Skeleton Acc | Contour Acc | Mean Acc | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: |:------: | -| [pose_resnet_50](/configs/top_down/resnet/mpii_trb/res50_mpii_trb_256x256.py) | 256x256 | 0.887 | 0.858 | 0.868 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_trb_256x256-896036b8_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_trb_256x256_20200812.log.json) | -| [pose_resnet_101](/configs/top_down/resnet/mpii_trb/res101_mpii_trb_256x256.py) | 256x256 | 0.890 | 0.863 | 0.873 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_trb_256x256-cfad2f05_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_trb_256x256_20200812.log.json) | -| [pose_resnet_152](/configs/top_down/resnet/mpii_trb/res152_mpii_trb_256x256.py) | 256x256 | 0.897 | 0.868 | 0.879 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_trb_256x256-dd369ce6_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_trb_256x256_20200812.log.json) | +| [pose_resnet_50](/configs/top_down/resnet/mpii_trb/res50_mpii_trb_256x256.py) | 256x256 | 0.887 | 0.858 | 0.868 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_trb_256x256-896036b8_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_mpii_trb_256x256_20200812.log.json) | +| [pose_resnet_101](/configs/top_down/resnet/mpii_trb/res101_mpii_trb_256x256.py) | 256x256 | 0.890 | 0.863 | 0.873 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_trb_256x256-cfad2f05_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_mpii_trb_256x256_20200812.log.json) | +| [pose_resnet_152](/configs/top_down/resnet/mpii_trb/res152_mpii_trb_256x256.py) | 256x256 | 0.897 | 0.868 | 0.879 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_trb_256x256-dd369ce6_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_mpii_trb_256x256_20200812.log.json) | diff --git a/configs/top_down/resnetv1d/README.md b/configs/top_down/resnetv1d/README.md index 463b36b371..9dac278a4f 100644 --- a/configs/top_down/resnetv1d/README.md +++ b/configs/top_down/resnetv1d/README.md @@ -17,18 +17,18 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnetv1d_50](/configs/top_down/resnetv1d/coco/resnetv1d50_coco_256x192.py) | 256x192 | 0.722 | 0.897 | 0.799 | 0.777 | 0.933 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192-a243b840_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192_20200727.log.json) | -| [pose_resnetv1d_50](/configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py) | 384x288 | 0.730 | 0.900 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_384x288-01f3fbb9_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_384x288_20200727.log.json) | -| [pose_resnetv1d_101](/configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py) | 256x192 | 0.731 | 0.899 | 0.809 | 0.786 | 0.938 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_256x192-5bd08cab_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_256x192_20200727.log.json) | -| [pose_resnetv1d_101](/configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py) | 384x288 | 0.748 | 0.902 | 0.816 | 0.799 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_384x288-5f9e421d_20200730.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_384x288-20200730.log.json) | -| [pose_resnetv1d_152](/configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py) | 256x192 | 0.737 | 0.902 | 0.812 | 0.791 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_256x192-c4df51dc_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_256x192_20200727.log.json) | -| [pose_resnetv1d_152](/configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py) | 384x288 | 0.752 | 0.909 | 0.821 | 0.802 | 0.944 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_384x288-626c622d_20200730.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_384x288-20200730.log.json) | +| [pose_resnetv1d_50](/configs/top_down/resnetv1d/coco/resnetv1d50_coco_256x192.py) | 256x192 | 0.722 | 0.897 | 0.799 | 0.777 | 0.933 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192-a243b840_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_256x192_20200727.log.json) | +| [pose_resnetv1d_50](/configs/top_down/resnetv1d/coco/resnetv1d50_coco_384x288.py) | 384x288 | 0.730 | 0.900 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_384x288-01f3fbb9_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_coco_384x288_20200727.log.json) | +| [pose_resnetv1d_101](/configs/top_down/resnetv1d/coco/resnetv1d101_coco_256x192.py) | 256x192 | 0.731 | 0.899 | 0.809 | 0.786 | 0.938 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_256x192-5bd08cab_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_256x192_20200727.log.json) | +| [pose_resnetv1d_101](/configs/top_down/resnetv1d/coco/resnetv1d101_coco_384x288.py) | 384x288 | 0.748 | 0.902 | 0.816 | 0.799 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_384x288-5f9e421d_20200730.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_coco_384x288-20200730.log.json) | +| [pose_resnetv1d_152](/configs/top_down/resnetv1d/coco/resnetv1d152_coco_256x192.py) | 256x192 | 0.737 | 0.902 | 0.812 | 0.791 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_256x192-c4df51dc_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_256x192_20200727.log.json) | +| [pose_resnetv1d_152](/configs/top_down/resnetv1d/coco/resnetv1d152_coco_384x288.py) | 384x288 | 0.752 | 0.909 | 0.821 | 0.802 | 0.944 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_384x288-626c622d_20200730.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_coco_384x288-20200730.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_resnetv1d_50](/configs/top_down/resnetv1d/mpii/resnetv1d50_mpii_256x256.py) | 256x256 | 0.881 | 0.331 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256-2337a92e_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256_20200812.log.json) | -| [pose_resnetv1d_101](/configs/top_down/resnetv1d/mpii/resnetv1d101_mpii_256x256.py) | 256x256 | 0.884 | 0.335 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256-2851d710_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256_20200812.log.json) | -| [pose_resnetv1d_152](/configs/top_down/resnetv1d/mpii/resnetv1d152_mpii_256x256.py) | 256x256 | 0.888 | 0.343 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256-8b10a87c_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256_20200812.log.json) | +| [pose_resnetv1d_50](/configs/top_down/resnetv1d/mpii/resnetv1d50_mpii_256x256.py) | 256x256 | 0.881 | 0.331 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256-2337a92e_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256_20200812.log.json) | +| [pose_resnetv1d_101](/configs/top_down/resnetv1d/mpii/resnetv1d101_mpii_256x256.py) | 256x256 | 0.884 | 0.335 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256-2851d710_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256_20200812.log.json) | +| [pose_resnetv1d_152](/configs/top_down/resnetv1d/mpii/resnetv1d152_mpii_256x256.py) | 256x256 | 0.888 | 0.343 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256-8b10a87c_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256_20200812.log.json) | diff --git a/configs/top_down/resnext/README.md b/configs/top_down/resnext/README.md index 186a5f05f8..a87681093d 100644 --- a/configs/top_down/resnext/README.md +++ b/configs/top_down/resnext/README.md @@ -17,9 +17,9 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_resnext_50](/configs/top_down/resnext/coco/resnext50_coco_256x192.py) | 256x192 | 0.714 | 0.898 | 0.789 | 0.771 | 0.937 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_256x192-dcff15f6_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_256x192_20200727.log.json) | -| [pose_resnext_50](/configs/top_down/resnext/coco/resnext50_coco_384x288.py) | 384x288 | 0.724 | 0.899 | 0.794 | 0.777 | 0.935 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_384x288-412c848f_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_384x288_20200727.log.json) | -| [pose_resnext_101](/configs/top_down/resnext/coco/resnext101_coco_256x192.py) | 256x192 | 0.726 | 0.900 | 0.801 | 0.782 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_256x192-c7eba365_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_256x192_20200727.log.json) | -| [pose_resnext_101](/configs/top_down/resnext/coco/resnext101_coco_384x288.py) | 384x288 | 0.743 | 0.903 | 0.815 | 0.795 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_384x288-f5eabcd6_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_384x288_20200727.log.json) | -| [pose_resnext_152](/configs/top_down/resnext/coco/resnext152_coco_256x192.py) | 256x192 | 0.730 | 0.904 | 0.808 | 0.786 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_256x192-102449aa_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_256x192_20200727.log.json) | -| [pose_resnext_152](/configs/top_down/resnext/coco/resnext152_coco_384x288.py) | 384x288 | 0.742 | 0.902 | 0.810 | 0.794 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_384x288-806176df_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_384x288_20200727.log.json) | +| [pose_resnext_50](/configs/top_down/resnext/coco/resnext50_coco_256x192.py) | 256x192 | 0.714 | 0.898 | 0.789 | 0.771 | 0.937 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_256x192-dcff15f6_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_256x192_20200727.log.json) | +| [pose_resnext_50](/configs/top_down/resnext/coco/resnext50_coco_384x288.py) | 384x288 | 0.724 | 0.899 | 0.794 | 0.777 | 0.935 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_384x288-412c848f_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext50_coco_384x288_20200727.log.json) | +| [pose_resnext_101](/configs/top_down/resnext/coco/resnext101_coco_256x192.py) | 256x192 | 0.726 | 0.900 | 0.801 | 0.782 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_256x192-c7eba365_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_256x192_20200727.log.json) | +| [pose_resnext_101](/configs/top_down/resnext/coco/resnext101_coco_384x288.py) | 384x288 | 0.743 | 0.903 | 0.815 | 0.795 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_384x288-f5eabcd6_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext101_coco_384x288_20200727.log.json) | +| [pose_resnext_152](/configs/top_down/resnext/coco/resnext152_coco_256x192.py) | 256x192 | 0.730 | 0.904 | 0.808 | 0.786 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_256x192-102449aa_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_256x192_20200727.log.json) | +| [pose_resnext_152](/configs/top_down/resnext/coco/resnext152_coco_384x288.py) | 384x288 | 0.742 | 0.902 | 0.810 | 0.794 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_384x288-806176df_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnext/resnext152_coco_384x288_20200727.log.json) | diff --git a/configs/top_down/scnet/README.md b/configs/top_down/scnet/README.md index 72690c33cc..01a01fe35b 100644 --- a/configs/top_down/scnet/README.md +++ b/configs/top_down/scnet/README.md @@ -17,15 +17,15 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_scnet_50](/configs/top_down/scnet/coco/scnet50_coco_256x192.py) | 256x192 | 0.728 | 0.899 | 0.807 | 0.784 | 0.938 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192_20200709.log.json) | -| [pose_scnet_50](/configs/top_down/scnet/coco/scnet50_coco_384x288.py) | 384x288 | 0.751 | 0.906 | 0.818 | 0.802 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288_20200709.log.json) | -| [pose_scnet_101](/configs/top_down/scnet/coco/scnet101_coco_256x192.py) | 256x192 | 0.733 | 0.903 | 0.813 | 0.790 | 0.941 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192_20200709.log.json) | -| [pose_scnet_101](/configs/top_down/scnet/coco/scnet101_coco_384x288.py) | 384x288 | 0.752 | 0.906 | 0.823 | 0.804 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288_20200709.log.json) | +| [pose_scnet_50](/configs/top_down/scnet/coco/scnet50_coco_256x192.py) | 256x192 | 0.728 | 0.899 | 0.807 | 0.784 | 0.938 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192_20200709.log.json) | +| [pose_scnet_50](/configs/top_down/scnet/coco/scnet50_coco_384x288.py) | 384x288 | 0.751 | 0.906 | 0.818 | 0.802 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288_20200709.log.json) | +| [pose_scnet_101](/configs/top_down/scnet/coco/scnet101_coco_256x192.py) | 256x192 | 0.733 | 0.903 | 0.813 | 0.790 | 0.941 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192_20200709.log.json) | +| [pose_scnet_101](/configs/top_down/scnet/coco/scnet101_coco_384x288.py) | 384x288 | 0.752 | 0.906 | 0.823 | 0.804 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288_20200709.log.json) | ### Results on MPII val set. | Arch | Input Size | Mean | Mean@0.1 | ckpt | log | | :--- | :--------: | :------: | :------: |:------: |:------: | -| [pose_scnet_50](/configs/top_down/scnet/mpii/scnet50_mpii_256x256.py) | 256x256 | 0.888 | 0.333 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_mpii_256x256-a54b6af5_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_mpii_256x256_20200812.log.json) | -| [pose_scnet_101](/configs/top_down/scnet/mpii/scnet101_mpii_256x256.py) | 256x256 | 0.886 | 0.334 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_mpii_256x256-b4c2d184_20200812.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_mpii_256x256_20200812.log.json) | +| [pose_scnet_50](/configs/top_down/scnet/mpii/scnet50_mpii_256x256.py) | 256x256 | 0.888 | 0.333 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_mpii_256x256-a54b6af5_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_mpii_256x256_20200812.log.json) | +| [pose_scnet_101](/configs/top_down/scnet/mpii/scnet101_mpii_256x256.py) | 256x256 | 0.886 | 0.334 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_mpii_256x256-b4c2d184_20200812.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_mpii_256x256_20200812.log.json) | diff --git a/configs/top_down/seresnet/README.md b/configs/top_down/seresnet/README.md index 584cbace24..d5080cffdf 100644 --- a/configs/top_down/seresnet/README.md +++ b/configs/top_down/seresnet/README.md @@ -17,11 +17,11 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_seresnet_50](/configs/top_down/seresnet/coco/seresnet50_coco_256x192.py) | 256x192 | 0.728 | 0.900 | 0.809 | 0.784 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_256x192-25058b66_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_256x192_20200727.log.json) | -| [pose_seresnet_50](/configs/top_down/seresnet/coco/seresnet50_coco_384x288.py) | 384x288 | 0.748 | 0.905 | 0.819 | 0.799 | 0.941 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_384x288-bc0b7680_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_384x288_20200727.log.json) | -| [pose_seresnet_101](/configs/top_down/seresnet/coco/seresnet101_coco_256x192.py) | 256x192 | 0.734 | 0.904 | 0.815 | 0.790 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_256x192-83f29c4d_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_256x192_20200727.log.json) | -| [pose_seresnet_101](/configs/top_down/seresnet/coco/seresnet101_coco_384x288.py) | 384x288 | 0.753 | 0.907 | 0.823 | 0.805 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_384x288-48de1709_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_384x288_20200727.log.json) | -| [pose_seresnet_152*](/configs/top_down/seresnet/coco/seresnet152_coco_256x192.py) | 256x192 | 0.730 | 0.899 | 0.810 | 0.786 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_256x192-1c628d79_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_256x192_20200727.log.json) | -| [pose_seresnet_152*](/configs/top_down/seresnet/coco/seresnet152_coco_384x288.py) | 384x288 | 0.753 | 0.906 | 0.823 | 0.806 | 0.945 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_384x288-58b23ee8_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_384x288_20200727.log.json) | +| [pose_seresnet_50](/configs/top_down/seresnet/coco/seresnet50_coco_256x192.py) | 256x192 | 0.728 | 0.900 | 0.809 | 0.784 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_256x192-25058b66_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_256x192_20200727.log.json) | +| [pose_seresnet_50](/configs/top_down/seresnet/coco/seresnet50_coco_384x288.py) | 384x288 | 0.748 | 0.905 | 0.819 | 0.799 | 0.941 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_384x288-bc0b7680_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet50_coco_384x288_20200727.log.json) | +| [pose_seresnet_101](/configs/top_down/seresnet/coco/seresnet101_coco_256x192.py) | 256x192 | 0.734 | 0.904 | 0.815 | 0.790 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_256x192-83f29c4d_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_256x192_20200727.log.json) | +| [pose_seresnet_101](/configs/top_down/seresnet/coco/seresnet101_coco_384x288.py) | 384x288 | 0.753 | 0.907 | 0.823 | 0.805 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_384x288-48de1709_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet101_coco_384x288_20200727.log.json) | +| [pose_seresnet_152*](/configs/top_down/seresnet/coco/seresnet152_coco_256x192.py) | 256x192 | 0.730 | 0.899 | 0.810 | 0.786 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_256x192-1c628d79_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_256x192_20200727.log.json) | +| [pose_seresnet_152*](/configs/top_down/seresnet/coco/seresnet152_coco_384x288.py) | 384x288 | 0.753 | 0.906 | 0.823 | 0.806 | 0.945 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_384x288-58b23ee8_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/seresnet/seresnet152_coco_384x288_20200727.log.json) | Note that * means without imagenet pre-training. diff --git a/configs/top_down/shufflenet_v1/README.md b/configs/top_down/shufflenet_v1/README.md index 42fef40d2d..8b5437e05a 100644 --- a/configs/top_down/shufflenet_v1/README.md +++ b/configs/top_down/shufflenet_v1/README.md @@ -17,5 +17,5 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| [pose_shufflenetv1](/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py) | 256x192 | 0.585 | 0.845 | 0.650 | 0.651 | 0.894 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_256x192-353bc02c_20200727.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_256x192_20200727.log.json) | -| [pose_shufflenetv1](/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py) | 384x288 | 0.622 | 0.859 | 0.685 | 0.684 | 0.901 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_384x288-b2930b24_20200804.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_384x288_20200804.log.json) | +| [pose_shufflenetv1](/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_256x192.py) | 256x192 | 0.585 | 0.845 | 0.650 | 0.651 | 0.894 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_256x192-353bc02c_20200727.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_256x192_20200727.log.json) | +| [pose_shufflenetv1](/configs/top_down/shufflenet_v1/coco/shufflenetv1_coco_384x288.py) | 384x288 | 0.622 | 0.859 | 0.685 | 0.684 | 0.901 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_384x288-b2930b24_20200804.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/shufflenetv1/shufflenetv1_coco_384x288_20200804.log.json) | diff --git a/docs/data_preparation.md b/docs/data_preparation.md index afe8aa5d21..ba79df7b4a 100644 --- a/docs/data_preparation.md +++ b/docs/data_preparation.md @@ -44,7 +44,7 @@ mmpose ``` **For MPII data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). -We have converted the original annotation files into json format, please download them from [mpii_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_annotations.tar). +We have converted the original annotation files into json format, please download them from [mpii_annotations](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/datasets/mpii_annotations.tar). Extract them under {MMPose}/data, and make them look like this: ``` @@ -69,7 +69,7 @@ mmpose ``` **For MPII-TRB data**, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/). -Please download the annotation files from [mpii_trb_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/mpii_trb_annotations.tar). +Please download the annotation files from [mpii_trb_annotations](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/datasets/mpii_trb_annotations.tar). Extract them under {MMPose}/data, and make them look like this: ``` @@ -91,7 +91,7 @@ mmpose ``` **For AIC data**, please download from [AI Challenger 2017](https://github.com/AIChallenger/AI_Challenger_2017), 2017 Train/Val is needed for keypoints training and validation. -Please download the annotation files from [aic_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/aic_annotations.tar). +Please download the annotation files from [aic_annotations](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/datasets/aic_annotations.tar). Download and extract them under $MMPOSE/data, and make them look like this: ``` @@ -119,7 +119,7 @@ mmpose ``` **For CrowdPose data**, please download from [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose). -Please download the annotation files from [crowdpose_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/aic_annotations.tar). +Please download the annotation files from [crowdpose_annotations](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/datasets/aic_annotations.tar). We follow [CrowdPose](https://arxiv.org/abs/1812.00324) to use the [pre-trained weights](https://pjreddie.com/media/files/yolov3.weights) of [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) to generate the detected human bounding boxes. Download and extract them under $MMPOSE/data, and make them look like this: @@ -168,7 +168,7 @@ mmpose ``` **For OneHand10K data**, please download from [OneHand10K Dataset](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html). -Please download the annotation files from [onehand10k_annotations](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/datasets/onehand10k_annotations.tar). +Please download the annotation files from [onehand10k_annotations](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/datasets/onehand10k_annotations.tar). Extract them under {MMPose}/data, and make them look like this: ``` diff --git a/docs/model_zoo.md b/docs/model_zoo.md index b3c57bc922..133fdfb114 100644 --- a/docs/model_zoo.md +++ b/docs/model_zoo.md @@ -8,22 +8,22 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| pose_resnet_50 | 256x192 | 0.718 | 0.898 | 0.795 | 0.773 | 0.937 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | -| pose_resnet_50 | 384x288 | 0.731 | 0.900 | 0.799 | 0.783 | 0.931 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | -| pose_resnet_101 | 256x192 | 0.726 | 0.899 | 0.806 | 0.781 | 0.939 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | -| pose_resnet_101 | 384x288 | 0.748 | 0.905 | 0.817 | 0.798 | 0.940 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | -| pose_resnet_152 | 256x192 | 0.735 | 0.905 | 0.812 | 0.790 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | -| pose_resnet_152 | 384x288 | 0.750 | 0.908 | 0.821 | 0.800 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | -| pose_hrnet_w32 | 256x192 | 0.746 | 0.904 | 0.819 | 0.799 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_20200708.log.json) | -| pose_hrnet_w32 | 384x288 | 0.760 | 0.906 | 0.829 | 0.810 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288-d9f0d786_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_20200708.log.json) | -| pose_hrnet_w48 | 256x192 | 0.756 | 0.907 | 0.825 | 0.806 | 0.942 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_20200708.log.json) | -| pose_hrnet_w48 | 384x288 | 0.767 | 0.910 | 0.831 | 0.816 | 0.946 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288-314c8528_20200708.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_20200708.log.json) | -| pose_scnet_50 | 256x192 | 0.728 | 0.899 | 0.807 | 0.784 | 0.938 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192_20200709.log.json) | -| pose_scnet_50 | 384x288 | 0.751 | 0.906 | 0.818 | 0.802 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288_20200709.log.json) | -| pose_scnet_101 | 256x192 | 0.733 | 0.903 | 0.813 | 0.790 | 0.941 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192_20200709.log.json) | -| pose_scnet_101 | 384x288 | 0.752 | 0.906 | 0.823 | 0.804 | 0.943 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288_20200709.log.json) | -| dark_pose_resnet_50 | 256x192 | 0.724 | 0.898 | 0.800 | 0.777 | 0.936 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark-43379d20_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark_20200709.log.json) | -| pose_hourglass_52 | 256x256 | 0.726 | 0.896 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256_20200709.log.json) | +| pose_resnet_50 | 256x192 | 0.718 | 0.898 | 0.795 | 0.773 | 0.937 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_20200709.log.json) | +| pose_resnet_50 | 384x288 | 0.731 | 0.900 | 0.799 | 0.783 | 0.931 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288-e6f795e9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_384x288_20200709.log.json) | +| pose_resnet_101 | 256x192 | 0.726 | 0.899 | 0.806 | 0.781 | 0.939 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192-6e6babf0_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_256x192_20200708.log.json) | +| pose_resnet_101 | 384x288 | 0.748 | 0.905 | 0.817 | 0.798 | 0.940 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288-8c71bdc9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res101_coco_384x288_20200709.log.json) | +| pose_resnet_152 | 256x192 | 0.735 | 0.905 | 0.812 | 0.790 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192-f6e307c2_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_256x192_20200709.log.json) | +| pose_resnet_152 | 384x288 | 0.750 | 0.908 | 0.821 | 0.800 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288-3860d4c9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res152_coco_384x288_20200709.log.json) | +| pose_hrnet_w32 | 256x192 | 0.746 | 0.904 | 0.819 | 0.799 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192_20200708.log.json) | +| pose_hrnet_w32 | 384x288 | 0.760 | 0.906 | 0.829 | 0.810 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288-d9f0d786_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w32_coco_384x288_20200708.log.json) | +| pose_hrnet_w48 | 256x192 | 0.756 | 0.907 | 0.825 | 0.806 | 0.942 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192_20200708.log.json) | +| pose_hrnet_w48 | 384x288 | 0.767 | 0.910 | 0.831 | 0.816 | 0.946 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288-314c8528_20200708.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hrnet/hrnet_w48_coco_384x288_20200708.log.json) | +| pose_scnet_50 | 256x192 | 0.728 | 0.899 | 0.807 | 0.784 | 0.938 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_256x192_20200709.log.json) | +| pose_scnet_50 | 384x288 | 0.751 | 0.906 | 0.818 | 0.802 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet50_coco_384x288_20200709.log.json) | +| pose_scnet_101 | 256x192 | 0.733 | 0.903 | 0.813 | 0.790 | 0.941 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_256x192_20200709.log.json) | +| pose_scnet_101 | 384x288 | 0.752 | 0.906 | 0.823 | 0.804 | 0.943 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/scnet/scnet101_coco_384x288_20200709.log.json) | +| dark_pose_resnet_50 | 256x192 | 0.724 | 0.898 | 0.800 | 0.777 | 0.936 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark-43379d20_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/resnet/res50_coco_256x192_dark_20200709.log.json) | +| pose_hourglass_52 | 256x256 | 0.726 | 0.896 | 0.799 | 0.780 | 0.934 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/top_down/hourglass/hourglass52_coco_256x256_20200709.log.json) | ### Bottom-Up Method: @@ -32,29 +32,29 @@ | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| HRNet-w32 | 512x512 | 0.677 | 0.870 | 0.738 | 0.723 | 0.890 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | -| HRNet-w32 | 640x640 | 0.686 | 0.871 | 0.747 | 0.733 | 0.898 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | -| HRNet-w48 | 512x512 | 0.686 | 0.873 | 0.741 | 0.731 | 0.892 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | +| HRNet-w32 | 512x512 | 0.677 | 0.870 | 0.738 | 0.723 | 0.890 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | +| HRNet-w32 | 640x640 | 0.686 | 0.871 | 0.747 | 0.733 | 0.898 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | +| HRNet-w48 | 512x512 | 0.686 | 0.873 | 0.741 | 0.731 | 0.892 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | #### Results on COCO val2017 with multi-scale test | Arch | Input Size | AP | AP50 | AP75 | AR | AR50 | ckpt | log | | :----------------- | :-----------: | :------: | :------: | :------: | :------: | :------: |:------: |:------: | -| HRNet-w32 | 512x512 | 0.706 | 0.881 | 0.771 | 0.747 | 0.901 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | -| HRNet-w32 | 640x640 | 0.706 | 0.880 | 0.770 | 0.749 | 0.902 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | -| HRNet-w48 | 512x512 | 0.716 | 0.884 | 0.775 | 0.755 | 0.901 | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | +| HRNet-w32 | 512x512 | 0.706 | 0.881 | 0.771 | 0.747 | 0.901 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512-8ae85183_20200713.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_512x512_20200713.log.json) | +| HRNet-w32 | 640x640 | 0.706 | 0.880 | 0.770 | 0.749 | 0.902 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640-a22fe938_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet32_coco_640x640_20200712.log.json) | +| HRNet-w48 | 512x512 | 0.716 | 0.884 | 0.775 | 0.755 | 0.901 | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512-60fedcbc_20200712.pth) | [log](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/bottom_up/higher_hrnet48_coco_512x512_20200712.log.json) | #### Pretrained backbones on ImageNet | Model | Checkpoint | Download | | :----------------- | :-----------: | :-----------: | -| resnet50 | resnet50-19c8e357.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/resnet50-19c8e357.pth) -| resnet101 | resnet101-5d3b4d8f.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/resnet101-5d3b4d8f.pth) -| resnet152 | resnet152-b121ed2d.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/resnet152-b121ed2d.pth) -| hrnet_w32 | hrnet_w32-36af842e.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth) | -| hrnet_w48 | hrnet_w48-8ef0771d.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/hrnet_w48-8ef0771d.pth) -| scnet50 | scnet50-7ef0a199.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/scnet50-7ef0a199.pth) -| scnet101 | scnet101-94250a77.pth | [ckpt](https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/pretrain_models/scnet101-94250a77.pth) +| resnet50 | resnet50-19c8e357.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/resnet50-19c8e357.pth) +| resnet101 | resnet101-5d3b4d8f.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/resnet101-5d3b4d8f.pth) +| resnet152 | resnet152-b121ed2d.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/resnet152-b121ed2d.pth) +| hrnet_w32 | hrnet_w32-36af842e.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth) | +| hrnet_w48 | hrnet_w48-8ef0771d.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/hrnet_w48-8ef0771d.pth) +| scnet50 | scnet50-7ef0a199.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/scnet50-7ef0a199.pth) +| scnet101 | scnet101-94250a77.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmpose/pretrain_models/scnet101-94250a77.pth) | resnetv1d50 | resnetv1d50_batch256_20200708-1ad0ce94.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmclassification/v0/imagenet/resnetv1d50_batch256_20200708-1ad0ce94.pth) | | resnetv1d101 | resnetv1d101_batch256_20200708-9cb302ef.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmclassification/v0/imagenet/resnetv1d101_batch256_20200708-9cb302ef.pth) | | resnetv1d152 | resnetv1d152_batch256_20200708-e79cb6a2.pth | [ckpt](https://openmmlab.oss-accelerate.aliyuncs.com/mmclassification/v0/imagenet/resnetv1d152_batch256_20200708-e79cb6a2.pth) | From b308cffb015b42f94663c659b658e81174bda348 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Wed, 26 Aug 2020 21:34:07 +0800 Subject: [PATCH 19/25] update readme --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index ed229a92b8..6428f83f84 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,11 @@ The master branch works with **PyTorch 1.3+**. We achieve faster training speed and higher accuracy than other popular codebases, such as [HRNet](https://github.com/leoxiaobin/deep-high-resolution-net.pytorch). See [benchmark.md](docs/benchmark.md) for more information. +- **Support for various datasets** + + The toolbox directly supports multiple datasets, COCO, AIC, MPII, MPII-TRB, OCHuman etc. + See [data_preparation.md](docs/data_preparation.md) for more information. + - **Well tested and documented** We provide detailed documentation and API reference, as well as unittests. @@ -66,6 +71,7 @@ More details about the benchmark are available on [benchmark.md](docs/benchmark. Supported backbones for human pose estimation: - [x] [AlexNet](configs/top_down/alexnet/README.md) +- [x] [CPM](configs/top_down/cpm/README.md) - [x] [Hourglass](configs/top_down/hourglass/README.md) - [x] [HRNet](configs/top_down/hrnet/README.md) - [x] [MobilenetV2](configs/top_down/mobilenet_v2/README.md) @@ -77,6 +83,7 @@ Supported backbones for human pose estimation: - [x] [ShufflenetV1](configs/top_down/shufflenet_v1/README.md) Supported methods for human pose estimation: +- [x] [CPM](configs/top_down/cpm/README.md) - [x] [SimpleBaseline](configs/top_down/resnet/README.md) - [x] [HRNet](configs/top_down/hrnet/README.md) - [x] [Hourglass](configs/top_down/hourglass/README.md) @@ -94,9 +101,15 @@ If you have any feature requests, please feel free to leave a comment in [Issues Please refer to [install.md](docs/install.md) for installation. +## Data Preparation + +Please refer to [data_preparation.md](docs/data_preparation.md) for a general knowledge of data preparation. + ## Get Started Please see [getting_started.md](docs/getting_started.md) for the basic usage of MMPose. +There are also tutorials for [finetuning model](tutorials/finetune.md), +[adding new dataset](tutorials/new_dataset.md), [adding new modules](tutorials/new_modules.md). ## License From cd94aca1ed5c2069510c4aa8036385d6d146fd03 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Thu, 27 Aug 2020 13:03:25 +0800 Subject: [PATCH 20/25] replace np.float with np.float32 --- mmpose/apis/inference.py | 25 ++++++++++++------- mmpose/core/evaluation/bottom_up_eval.py | 2 -- mmpose/core/evaluation/top_down_eval.py | 3 ++- mmpose/core/post_processing/nms.py | 2 +- .../datasets/bottom_up/bottom_up_coco.py | 6 +++-- .../datasets/top_down/topdown_aic_dataset.py | 4 +-- .../datasets/top_down/topdown_coco_dataset.py | 8 +++--- .../datasets/top_down/topdown_mpii_dataset.py | 6 ++--- .../top_down/topdown_mpii_trb_dataset.py | 4 +-- .../top_down/topdown_ochuman_dataset.py | 4 +-- .../top_down/topdown_onehand10k_dataset.py | 4 +-- .../datasets/pipelines/bottom_up_transform.py | 7 +++--- mmpose/models/detectors/top_down.py | 2 +- tests/test_evaluation/test_top_down_eval.py | 6 ++--- tests/test_model/test_bottom_up_forward.py | 6 ++--- tests/test_model/test_top_down_forward.py | 4 +-- .../test_bottom_up_pipelines.py | 8 +++--- .../test_pipelines/test_top_down_pipelines.py | 4 +-- 18 files changed, 58 insertions(+), 47 deletions(-) diff --git a/mmpose/apis/inference.py b/mmpose/apis/inference.py index e5200a4e9d..29b40d7fc4 100644 --- a/mmpose/apis/inference.py +++ b/mmpose/apis/inference.py @@ -155,15 +155,22 @@ def _inference_single_pose_model(model, img_or_path, bbox): center, scale = _box2cs(cfg, bbox) # prepare data data = { - 'img_or_path': img_or_path, - 'center': center, - 'scale': scale, - 'bbox_score': bbox[4] if len(bbox) == 5 else 1, - 'dataset': 'coco', - 'joints_3d': np.zeros((cfg.data_cfg.num_joints, 3), dtype=np.float), - 'joints_3d_visible': np.zeros((cfg.data_cfg.num_joints, 3), - dtype=np.float), - 'rotation': 0, + 'img_or_path': + img_or_path, + 'center': + center, + 'scale': + scale, + 'bbox_score': + bbox[4] if len(bbox) == 5 else 1, + 'dataset': + 'coco', + 'joints_3d': + np.zeros((cfg.data_cfg.num_joints, 3), dtype=np.float32), + 'joints_3d_visible': + np.zeros((cfg.data_cfg.num_joints, 3), dtype=np.float32), + 'rotation': + 0, 'ann_info': { 'image_size': cfg.data_cfg['image_size'], diff --git a/mmpose/core/evaluation/bottom_up_eval.py b/mmpose/core/evaluation/bottom_up_eval.py index e585a2adca..64c60a2f2f 100644 --- a/mmpose/core/evaluation/bottom_up_eval.py +++ b/mmpose/core/evaluation/bottom_up_eval.py @@ -1,4 +1,3 @@ -import numpy as np import torch from mmpose.core.post_processing import transform_preds @@ -184,7 +183,6 @@ def get_group_preds(grouped_joints, center, scale, heatmap_size): """ results = [] for person in grouped_joints[0]: - joints = np.zeros((person.shape[0], 3)) joints = transform_preds(person, center, scale, heatmap_size) results.append(joints) diff --git a/mmpose/core/evaluation/top_down_eval.py b/mmpose/core/evaluation/top_down_eval.py index 979931378b..9cadae46cd 100644 --- a/mmpose/core/evaluation/top_down_eval.py +++ b/mmpose/core/evaluation/top_down_eval.py @@ -196,7 +196,8 @@ def _gaussian_blur(heatmaps, kernel=11): for i in range(batch_size): for j in range(num_joints): origin_max = np.max(heatmaps[i, j]) - dr = np.zeros((height + 2 * border, width + 2 * border)) + dr = np.zeros((height + 2 * border, width + 2 * border), + dtype=np.float32) dr[border:-border, border:-border] = heatmaps[i, j].copy() dr = cv2.GaussianBlur(dr, (kernel, kernel), 0) heatmaps[i, j] = dr[border:-border, border:-border].copy() diff --git a/mmpose/core/post_processing/nms.py b/mmpose/core/post_processing/nms.py index d9185cb2bf..3501d8c1f8 100644 --- a/mmpose/core/post_processing/nms.py +++ b/mmpose/core/post_processing/nms.py @@ -71,7 +71,7 @@ def oks_iou(g, d, a_g, a_d, sigmas=None, vis_thr=None): xg = g[0::3] yg = g[1::3] vg = g[2::3] - ious = np.zeros(len(d)) + ious = np.zeros(len(d), dtype=np.float32) for n_d in range(0, len(d)): xd = d[n_d, 0::3] yd = d[n_d, 1::3] diff --git a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py index 06e086db1c..a6c3759fb0 100644 --- a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py +++ b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py @@ -141,9 +141,11 @@ def _get_joints(self, anno): num_people = len(anno) if self.ann_info['scale_aware_sigma']: - joints = np.zeros((num_people, self.ann_info['num_joints'], 4)) + joints = np.zeros((num_people, self.ann_info['num_joints'], 4), + dtype=np.float32) else: - joints = np.zeros((num_people, self.ann_info['num_joints'], 3)) + joints = np.zeros((num_people, self.ann_info['num_joints'], 3), + dtype=np.float32) for i, obj in enumerate(anno): joints[i, :self.ann_info['num_joints'], :3] = \ diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index a420255ea9..2ff154dfb3 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -163,8 +163,8 @@ def _load_coco_keypoint_annotation_kernel(self, index): for obj in objs: if max(obj['keypoints']) == 0: continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) keypoints = np.array(obj['keypoints']).reshape(-1, 3) joints_3d[:, :2] = keypoints[:, :2] diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index ccb75f93dc..0ea5034c9f 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -157,8 +157,8 @@ def _load_coco_keypoint_annotation_kernel(self, index): for obj in objs: if max(obj['keypoints']) == 0: continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) for ipt in range(num_joints): joints_3d[ipt, 0] = obj['keypoints'][ipt * 3 + 0] joints_3d[ipt, 1] = obj['keypoints'][ipt * 3 + 1] @@ -246,8 +246,8 @@ def _load_coco_person_detection_results(self): num_boxes = num_boxes + 1 center, scale = self._xywh2cs(*box[:4]) - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.ones((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.ones((num_joints, 3), dtype=np.float32) kpt_db.append({ 'image_file': img_name, 'center': center, diff --git a/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py b/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py index c868c62bb4..608efd54b7 100644 --- a/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py @@ -80,9 +80,9 @@ def _get_db(self): center = center - 1 joints_3d = np.zeros((self.ann_info['num_joints'], 3), - dtype=np.float) + dtype=np.float32) joints_3d_visible = np.zeros((self.ann_info['num_joints'], 3), - dtype=np.float) + dtype=np.float32) if not self.test_mode: joints = np.array(a['joints']) joints_vis = np.array(a['joints_vis']) @@ -194,7 +194,7 @@ def evaluate(self, outputs, res_folder, metric='PCKh', **kwargs): # save rng = np.arange(0, 0.5 + 0.01, 0.01) - pckAll = np.zeros((len(rng), 16)) + pckAll = np.zeros((len(rng), 16), dtype=np.float32) for r, threshold in enumerate(rng): less_than_threshold = (scaled_uv_err <= threshold) * jnt_visible diff --git a/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py b/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py index 61f165ee35..c33dd32116 100644 --- a/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py @@ -96,8 +96,8 @@ def _get_db(self, ann_file): if max(anno['keypoints']) == 0: continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) for ipt in range(num_joints): joints_3d[ipt, 0] = anno['keypoints'][ipt * 3 + 0] diff --git a/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py b/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py index d4743d30ac..470a486ade 100644 --- a/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py @@ -166,8 +166,8 @@ def _load_coco_keypoint_annotation_kernel(self, index): for obj in objs: if max(obj['keypoints']) == 0: continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) keypoints = np.array(obj['keypoints']).reshape(-1, 3) joints_3d[:, :2] = keypoints[:, :2] diff --git a/mmpose/datasets/datasets/top_down/topdown_onehand10k_dataset.py b/mmpose/datasets/datasets/top_down/topdown_onehand10k_dataset.py index ec016186ab..d05fada05e 100644 --- a/mmpose/datasets/datasets/top_down/topdown_onehand10k_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_onehand10k_dataset.py @@ -108,8 +108,8 @@ def _get_db(self, ann_file): if max(anno['keypoints']) == 0: continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) for ipt in range(num_joints): joints_3d[ipt, 0] = anno['keypoints'][ipt * 3 + 0] diff --git a/mmpose/datasets/pipelines/bottom_up_transform.py b/mmpose/datasets/pipelines/bottom_up_transform.py index 7c27c6198d..b9ed9ee44e 100644 --- a/mmpose/datasets/pipelines/bottom_up_transform.py +++ b/mmpose/datasets/pipelines/bottom_up_transform.py @@ -153,7 +153,8 @@ def __call__(self, joints): Returns: visible_kpts (np.ndarray[MxKx2]). """ - visible_kpts = np.zeros((self.max_num_people, self.num_joints, 2)) + visible_kpts = np.zeros((self.max_num_people, self.num_joints, 2), + dtype=np.float32) output_res = self.output_res for i in range(len(joints)): tot = 0 @@ -226,7 +227,7 @@ def __init__(self, rot_factor, scale_factor, scale_type, trans_factor): def _get_affine_matrix(self, center, scale, res, rot=0): """Generate transformation matrix.""" h = scale - t = np.zeros((3, 3)) + t = np.zeros((3, 3), dtype=np.float32) t[0, 0] = float(res[1]) / h t[1, 1] = float(res[0]) / h t[0, 2] = res[1] * (-float(center[0]) / h + .5) @@ -234,7 +235,7 @@ def _get_affine_matrix(self, center, scale, res, rot=0): t[2, 2] = 1 if rot != 0: rot = -rot # To match direction of rotation from cropping - rot_mat = np.zeros((3, 3)) + rot_mat = np.zeros((3, 3), dtype=np.float32) rot_rad = rot * np.pi / 180 sn, cs = np.sin(rot_rad), np.cos(rot_rad) rot_mat[0, :2] = [cs, -sn] diff --git a/mmpose/models/detectors/top_down.py b/mmpose/models/detectors/top_down.py index 3095686387..c0ea6748e8 100644 --- a/mmpose/models/detectors/top_down.py +++ b/mmpose/models/detectors/top_down.py @@ -195,7 +195,7 @@ def forward_test(self, img, img_metas, **kwargs): kernel=self.test_cfg['modulate_kernel']) all_preds = np.zeros((1, output.shape[1], 3), dtype=np.float32) - all_boxes = np.zeros((1, 6)) + all_boxes = np.zeros((1, 6), dtype=np.float32) image_path = [] all_preds[0, :, 0:2] = preds[:, :, 0:2] diff --git a/tests/test_evaluation/test_top_down_eval.py b/tests/test_evaluation/test_top_down_eval.py index a4731cef3a..aff912dfbf 100644 --- a/tests/test_evaluation/test_top_down_eval.py +++ b/tests/test_evaluation/test_top_down_eval.py @@ -6,8 +6,8 @@ def test_pose_pck_accuracy(): - output = np.zeros((1, 5, 64, 64)) - target = np.zeros((1, 5, 64, 64)) + output = np.zeros((1, 5, 64, 64), dtype=np.float32) + target = np.zeros((1, 5, 64, 64), dtype=np.float32) # first channnel output[0, 0, 20, 20] = 1 target[0, 0, 10, 10] = 1 @@ -23,7 +23,7 @@ def test_pose_pck_accuracy(): def test_keypoints_from_heatmaps(): - heatmaps = np.ones((1, 1, 64, 64)) + heatmaps = np.ones((1, 1, 64, 64), dtype=np.float32) heatmaps[0, 0, 31, 31] = 2 center = np.array([[127, 127]]) scale = np.array([[64 / 200.0, 64 / 200.0]]) diff --git a/tests/test_model/test_bottom_up_forward.py b/tests/test_model/test_bottom_up_forward.py index 6207104ccc..23358ef244 100644 --- a/tests/test_model/test_bottom_up_forward.py +++ b/tests/test_model/test_bottom_up_forward.py @@ -92,9 +92,9 @@ def _demo_mm_inputs(input_shape=(1, 3, 256, 256)): rng = np.random.RandomState(0) imgs = rng.rand(*input_shape) - target = np.zeros([N, 17, H // 32, W // 32]) - mask = np.ones([N, H // 32, W // 32]) - joints = np.zeros([N, 30, 17, 2]) + target = np.zeros([N, 17, H // 32, W // 32], dtype=np.float32) + mask = np.ones([N, H // 32, W // 32], dtype=np.float32) + joints = np.zeros([N, 30, 17, 2], dtype=np.float32) img_metas = [{ 'image_file': diff --git a/tests/test_model/test_top_down_forward.py b/tests/test_model/test_top_down_forward.py index bcb3fbf3a2..c8ccc7da6a 100644 --- a/tests/test_model/test_top_down_forward.py +++ b/tests/test_model/test_top_down_forward.py @@ -97,8 +97,8 @@ def _demo_mm_inputs(input_shape=(1, 3, 256, 256)): rng = np.random.RandomState(0) imgs = rng.rand(*input_shape) - target = np.zeros([N, 17, H // 4, W // 4]) - target_weight = np.ones([N, 17]) + target = np.zeros([N, 17, H // 4, W // 4], dtype=np.float32) + target_weight = np.ones([N, 17], dtype=np.float32) img_metas = [{ 'img_shape': (H, W, C), diff --git a/tests/test_pipelines/test_bottom_up_pipelines.py b/tests/test_pipelines/test_bottom_up_pipelines.py index f12b2d5064..16b5e18091 100644 --- a/tests/test_pipelines/test_bottom_up_pipelines.py +++ b/tests/test_pipelines/test_bottom_up_pipelines.py @@ -16,7 +16,7 @@ def _get_mask(coco, anno, img_id): img_info = coco.loadImgs(img_id)[0] - m = np.zeros((img_info['height'], img_info['width'])) + m = np.zeros((img_info['height'], img_info['width']), dtype=np.float32) for obj in anno: if obj['iscrowd']: @@ -38,9 +38,11 @@ def _get_joints(anno, ann_info, int_sigma): num_people = len(anno) if ann_info['scale_aware_sigma']: - joints = np.zeros((num_people, ann_info['num_joints'], 4)) + joints = np.zeros((num_people, ann_info['num_joints'], 4), + dtype=np.float32) else: - joints = np.zeros((num_people, ann_info['num_joints'], 3)) + joints = np.zeros((num_people, ann_info['num_joints'], 3), + dtype=np.float32) for i, obj in enumerate(anno): joints[i, :ann_info['num_joints'], :3] = \ diff --git a/tests/test_pipelines/test_top_down_pipelines.py b/tests/test_pipelines/test_top_down_pipelines.py index 3c112efaf0..5ba61b3571 100644 --- a/tests/test_pipelines/test_top_down_pipelines.py +++ b/tests/test_pipelines/test_top_down_pipelines.py @@ -82,8 +82,8 @@ def test_top_down_pipeline(): ann = coco.anns[ann_ids[0]] num_joints = 17 - joints_3d = np.zeros((num_joints, 3), dtype=np.float) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float) + joints_3d = np.zeros((num_joints, 3), dtype=np.float32) + joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) for ipt in range(num_joints): joints_3d[ipt, 0] = ann['keypoints'][ipt * 3 + 0] joints_3d[ipt, 1] = ann['keypoints'][ipt * 3 + 1] From 78170b0152abc2c1d50766736d6140a2c5d1e2cd Mon Sep 17 00:00:00 2001 From: jinsheng Date: Thu, 27 Aug 2020 20:01:17 +0800 Subject: [PATCH 21/25] subclass COCO --- .../datasets/top_down/topdown_aic_dataset.py | 170 +----------------- .../datasets/top_down/topdown_coco_dataset.py | 68 ++++--- .../top_down/topdown_ochuman_dataset.py | 168 +---------------- 3 files changed, 50 insertions(+), 356 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 2ff154dfb3..359824813e 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -1,33 +1,11 @@ -import os -from collections import OrderedDict, defaultdict - import numpy as np from xtcocotools.coco import COCO from xtcocotools.cocoeval import COCOeval -from ....core.post_processing import oks_nms, soft_oks_nms from ...registry import DATASETS from .topdown_coco_dataset import TopDownCocoDataset -def _get_mapping_id_name(imgs): - """ - Args: - imgs (dict): dict of image info. - Returns: - id2name (dict): mapping image id to name. - name2id (dict): mapping image name to id. - """ - id2name = {} - name2id = {} - for image_id, image in imgs.items(): - file_name = image['file_name'] - id2name[image_id] = file_name - name2id[file_name] = image_id - - return id2name, name2id - - @DATASETS.register_module() class TopDownAicDataset(TopDownCocoDataset): """AicDataset dataset for top-down pose estimation. @@ -114,7 +92,8 @@ def __init__(self, for cls in self.classes[1:]) self.image_set_index = self.coco.getImgIds() self.num_images = len(self.image_set_index) - self.id2name, self.name2id = _get_mapping_id_name(self.coco.imgs) + self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs) + self.dataset_name = 'aic' self.db = self._get_db() @@ -127,151 +106,8 @@ def _get_db(self): gt_db = self._load_coco_keypoint_annotations() return gt_db - def _load_coco_keypoint_annotation_kernel(self, index): - """load annotation from COCOAPI. - - Note: - bbox:[x1, y1, w, h] - Args: - index: coco image id - Returns: - db entry - """ - im_ann = self.coco.loadImgs(index)[0] - width = im_ann['width'] - height = im_ann['height'] - num_joints = self.ann_info['num_joints'] - - ann_ids = self.coco.getAnnIds(imgIds=index) - objs = self.coco.loadAnns(ann_ids) - - # sanitize bboxes - valid_objs = [] - for obj in objs: - x, y, w, h = obj['bbox'] - x1 = max(0, x) - y1 = max(0, y) - x2 = min(width - 1, x1 + max(0, w - 1)) - y2 = min(height - 1, y1 + max(0, h - 1)) - if ('area' not in obj - or obj['area'] > 0) and x2 >= x1 and y2 >= y1: - obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1] - valid_objs.append(obj) - objs = valid_objs - - rec = [] - for obj in objs: - if max(obj['keypoints']) == 0: - continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float32) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) - - keypoints = np.array(obj['keypoints']).reshape(-1, 3) - joints_3d[:, :2] = keypoints[:, :2] - joints_3d_visible[:, :2] = np.minimum(1, keypoints[:, 2:3]) - - center, scale = self._xywh2cs(*obj['clean_bbox'][:4]) - - image_file = os.path.join(self.img_prefix, self.id2name[index]) - rec.append({ - 'image_file': image_file, - 'center': center, - 'scale': scale, - 'rotation': 0, - 'joints_3d': joints_3d, - 'joints_3d_visible': joints_3d_visible, - 'dataset': 'aic', - 'bbox_score': 1 - }) - - return rec - - def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): - """Evaluate coco keypoint results. The pose prediction results will be - saved in `${res_folder}/result_keypoints.json`. - - Note: - num_keypoints: K - - Args: - outputs (list(preds, boxes, image_path)) - :preds (np.ndarray[1,K,3]): The first two dimensions are - coordinates, score is the third dimension of the array. - :boxes (np.ndarray[1,6]): [center[0], center[1], scale[0] - , scale[1],area, score] - :image_path (list[str]): For example, [ '/', 'v','a', 'l', - '2', '0', '1', '7', '/', '0', '0', '0', '0', '0', - '0', '3', '9', '7', '1', '3', '3', '.', 'j', 'p', 'g'] - res_folder (str): Path of directory to save the results. - metric (str): Metric to be performed. Defaults: 'mAP'. - - Returns: - name_value (dict): Evaluation results for evaluation metric. - """ - assert metric == 'mAP' - - res_file = os.path.join(res_folder, 'result_keypoints.json') - - kpts = defaultdict(list) - for preds, boxes, image_path in outputs: - str_image_path = ''.join(image_path) - image_id = self.name2id[os.path.basename(str_image_path)] - - kpts[image_id].append({ - 'keypoints': preds[0], - 'center': boxes[0][0:2], - 'scale': boxes[0][2:4], - 'area': boxes[0][4], - 'score': boxes[0][5], - 'image_id': image_id, - }) - - # rescoring and oks nms - num_joints = self.ann_info['num_joints'] - vis_thr = self.vis_thr - oks_thr = self.oks_thr - oks_nmsed_kpts = [] - for img in kpts.keys(): - img_kpts = kpts[img] - for n_p in img_kpts: - box_score = n_p['score'] - kpt_score = 0 - valid_num = 0 - for n_jt in range(0, num_joints): - t_s = n_p['keypoints'][n_jt][2] - if t_s > vis_thr: - kpt_score = kpt_score + t_s - valid_num = valid_num + 1 - if valid_num != 0: - kpt_score = kpt_score / valid_num - # rescoring - n_p['score'] = kpt_score * box_score - - if self.soft_nms: - keep = soft_oks_nms( - [img_kpts[i] for i in range(len(img_kpts))], - oks_thr, - sigmas=self.sigmas) - else: - keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))], - oks_thr, - sigmas=self.sigmas) - - if len(keep) == 0: - oks_nmsed_kpts.append(img_kpts) - else: - oks_nmsed_kpts.append([img_kpts[_keep] for _keep in keep]) - - self._write_coco_keypoint_results(oks_nmsed_kpts, res_file) - - info_str = self._do_python_keypoint_eval(res_file) - name_value = OrderedDict(info_str) - - return name_value - def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" - coco_dt = self.coco.loadRes(res_file) coco_eval = COCOeval( self.coco, coco_dt, 'keypoints', self.sigmas, use_area=False) @@ -281,7 +117,7 @@ def _do_python_keypoint_eval(self, res_file): coco_eval.summarize() stats_names = [ - 'AP', 'Ap .5', 'AP .75', 'AP (M)', 'AP (L)', 'AR', 'AR .5', + 'AP', 'AP .5', 'AP .75', 'AP (M)', 'AP (L)', 'AR', 'AR .5', 'AR .75', 'AR (M)', 'AR (L)' ] diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index 0ea5034c9f..2afa3619ff 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -1,5 +1,4 @@ import os -import os.path as osp from collections import OrderedDict, defaultdict import json_tricks as json @@ -86,6 +85,11 @@ def __init__(self, ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) + self.sigmas = np.array([ + .26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07, + .87, .87, .89, .89 + ]) / 10.0 + self.coco = COCO(ann_file) cats = [ @@ -100,11 +104,31 @@ def __init__(self, for cls in self.classes[1:]) self.image_set_index = self.coco.getImgIds() self.num_images = len(self.image_set_index) + self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs) + self.dataset_name = 'coco' + self.db = self._get_db() print(f'=> num_images: {self.num_images}') print(f'=> load {len(self.db)} samples') + def _get_mapping_id_name(self, imgs): + """ + Args: + imgs (dict): dict of image info. + Returns: + id2name (dict): mapping image id to name. + name2id (dict): mapping image name to id. + """ + id2name = {} + name2id = {} + for image_id, image in imgs.items(): + file_name = image['file_name'] + id2name[image_id] = file_name + name2id[file_name] = image_id + + return id2name, name2id + def _get_db(self): """Load dataset.""" if (not self.test_mode) or self.use_gt_bbox: @@ -148,7 +172,8 @@ def _load_coco_keypoint_annotation_kernel(self, index): y1 = max(0, y) x2 = min(width - 1, x1 + max(0, w - 1)) y2 = min(height - 1, y1 + max(0, h - 1)) - if obj['area'] > 0 and x2 >= x1 and y2 >= y1: + if ('area' not in obj + or obj['area'] > 0) and x2 >= x1 and y2 >= y1: obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1] valid_objs.append(obj) objs = valid_objs @@ -159,26 +184,22 @@ def _load_coco_keypoint_annotation_kernel(self, index): continue joints_3d = np.zeros((num_joints, 3), dtype=np.float32) joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) - for ipt in range(num_joints): - joints_3d[ipt, 0] = obj['keypoints'][ipt * 3 + 0] - joints_3d[ipt, 1] = obj['keypoints'][ipt * 3 + 1] - joints_3d[ipt, 2] = 0 - t_vis = obj['keypoints'][ipt * 3 + 2] - if t_vis > 1: - t_vis = 1 - joints_3d_visible[ipt, 0] = t_vis - joints_3d_visible[ipt, 1] = t_vis - joints_3d_visible[ipt, 2] = 0 + + keypoints = np.array(obj['keypoints']).reshape(-1, 3) + joints_3d[:, :2] = keypoints[:, :2] + joints_3d_visible[:, :2] = np.minimum(1, keypoints[:, 2:3]) center, scale = self._xywh2cs(*obj['clean_bbox'][:4]) + + image_file = os.path.join(self.img_prefix, self.id2name[index]) rec.append({ - 'image_file': self._image_path_from_index(index), + 'image_file': image_file, 'center': center, 'scale': scale, 'rotation': 0, 'joints_3d': joints_3d, 'joints_3d_visible': joints_3d_visible, - 'dataset': 'coco', + 'dataset': self.dataset_name, 'bbox_score': 1 }) @@ -213,11 +234,6 @@ def _xywh2cs(self, x, y, w, h): return center, scale - def _image_path_from_index(self, index): - """ example: images/train2017/000000119993.jpg """ - image_path = os.path.join(self.img_prefix, '%012d.jpg' % index) - return image_path - def _load_coco_person_detection_results(self): """Load coco person detection results.""" num_joints = self.ann_info['num_joints'] @@ -236,7 +252,7 @@ def _load_coco_person_detection_results(self): if det_res['category_id'] != 1: continue - img_name = self._image_path_from_index(det_res['image_id']) + img_name = self.id2name[det_res['image_id']] box = det_res['bbox'] score = det_res['score'] @@ -291,7 +307,7 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): kpts = defaultdict(list) for preds, boxes, image_path in outputs: str_image_path = ''.join(image_path) - image_id = int(osp.basename(osp.splitext(str_image_path)[0])) + image_id = self.name2id[os.path.basename(str_image_path)] kpts[image_id].append({ 'keypoints': preds[0], @@ -323,12 +339,8 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): # rescoring n_p['score'] = kpt_score * box_score - if self.soft_nms: - keep = soft_oks_nms( - [img_kpts[i] for i in range(len(img_kpts))], oks_thr) - else: - keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))], - oks_thr) + nms = soft_oks_nms if self.soft_nms else oks_nms + keep = nms(list(img_kpts), oks_thr, sigmas=self.sigmas) if len(keep) == 0: oks_nmsed_kpts.append(img_kpts) @@ -389,7 +401,7 @@ def _coco_keypoint_results_one_category_kernel(self, data_pack): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(self.coco, coco_dt, 'keypoints') + coco_eval = COCOeval(self.coco, coco_dt, 'keypoints', self.sigmas) coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() diff --git a/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py b/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py index 470a486ade..73aa299fc3 100644 --- a/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_ochuman_dataset.py @@ -1,32 +1,10 @@ -import os -from collections import OrderedDict, defaultdict - import numpy as np from xtcocotools.coco import COCO -from ....core.post_processing import oks_nms, soft_oks_nms from ...registry import DATASETS from .topdown_coco_dataset import TopDownCocoDataset -def _get_mapping_id_name(imgs): - """ - Args: - imgs (dict): dict of image info. - Returns: - id2name (dict): mapping image id to name. - name2id (dict): mapping image name to id. - """ - id2name = {} - name2id = {} - for image_id, image in imgs.items(): - file_name = image['file_name'] - id2name[image_id] = file_name - name2id[file_name] = image_id - - return id2name, name2id - - @DATASETS.register_module() class TopDownOCHumanDataset(TopDownCocoDataset): """OChuman dataset for top-down pose estimation. @@ -104,6 +82,11 @@ def __init__(self, ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1)) + self.sigmas = np.array([ + .26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07, + .87, .87, .89, .89 + ]) / 10.0 + self.coco = COCO(ann_file) cats = [ @@ -118,7 +101,8 @@ def __init__(self, for cls in self.classes[1:]) self.image_set_index = self.coco.getImgIds() self.num_images = len(self.image_set_index) - self.id2name, self.name2id = _get_mapping_id_name(self.coco.imgs) + self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs) + self.dataset_name = 'ochuman' self.db = self._get_db() @@ -130,141 +114,3 @@ def _get_db(self): assert self.use_gt_bbox gt_db = self._load_coco_keypoint_annotations() return gt_db - - def _load_coco_keypoint_annotation_kernel(self, index): - """load annotation from COCOAPI. - - Note: - bbox:[x1, y1, w, h] - Args: - index: coco image id - Returns: - db entry - """ - im_ann = self.coco.loadImgs(index)[0] - width = im_ann['width'] - height = im_ann['height'] - num_joints = self.ann_info['num_joints'] - - ann_ids = self.coco.getAnnIds(imgIds=index, iscrowd=False) - objs = self.coco.loadAnns(ann_ids) - - # sanitize bboxes - valid_objs = [] - for obj in objs: - x, y, w, h = obj['bbox'] - x1 = max(0, x) - y1 = max(0, y) - x2 = min(width - 1, x1 + max(0, w - 1)) - y2 = min(height - 1, y1 + max(0, h - 1)) - if obj['area'] > 0 and x2 >= x1 and y2 >= y1: - obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1] - valid_objs.append(obj) - objs = valid_objs - - rec = [] - for obj in objs: - if max(obj['keypoints']) == 0: - continue - joints_3d = np.zeros((num_joints, 3), dtype=np.float32) - joints_3d_visible = np.zeros((num_joints, 3), dtype=np.float32) - - keypoints = np.array(obj['keypoints']).reshape(-1, 3) - joints_3d[:, :2] = keypoints[:, :2] - joints_3d_visible[:, :2] = np.minimum(1, keypoints[:, 2:3]) - - center, scale = self._xywh2cs(*obj['clean_bbox'][:4]) - - image_file = os.path.join(self.img_prefix, self.id2name[index]) - rec.append({ - 'image_file': image_file, - 'center': center, - 'scale': scale, - 'rotation': 0, - 'joints_3d': joints_3d, - 'joints_3d_visible': joints_3d_visible, - 'dataset': 'ochuman', - 'bbox_score': 1 - }) - - return rec - - def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): - """Evaluate coco keypoint results. The pose prediction results will be - saved in `${res_folder}/result_keypoints.json`. - - Note: - num_keypoints: K - - Args: - outputs (list(preds, boxes, image_path)) - :preds (np.ndarray[1,K,3]): The first two dimensions are - coordinates, score is the third dimension of the array. - :boxes (np.ndarray[1,6]): [center[0], center[1], scale[0] - , scale[1],area, score] - :image_path (list[str]): For example, [ '/', 'v','a', 'l', - '2', '0', '1', '7', '/', '0', '0', '0', '0', '0', - '0', '3', '9', '7', '1', '3', '3', '.', 'j', 'p', 'g'] - res_folder (str): Path of directory to save the results. - metric (str): Metric to be performed. Defaults: 'mAP'. - - Returns: - name_value (dict): Evaluation results for evaluation metric. - """ - assert metric == 'mAP' - - res_file = os.path.join(res_folder, 'result_keypoints.json') - - kpts = defaultdict(list) - for preds, boxes, image_path in outputs: - str_image_path = ''.join(image_path) - image_id = self.name2id[os.path.basename(str_image_path)] - - kpts[image_id].append({ - 'keypoints': preds[0], - 'center': boxes[0][0:2], - 'scale': boxes[0][2:4], - 'area': boxes[0][4], - 'score': boxes[0][5], - 'image_id': image_id, - }) - - # rescoring and oks nms - num_joints = self.ann_info['num_joints'] - vis_thr = self.vis_thr - oks_thr = self.oks_thr - oks_nmsed_kpts = [] - for img in kpts.keys(): - img_kpts = kpts[img] - for n_p in img_kpts: - box_score = n_p['score'] - kpt_score = 0 - valid_num = 0 - for n_jt in range(0, num_joints): - t_s = n_p['keypoints'][n_jt][2] - if t_s > vis_thr: - kpt_score = kpt_score + t_s - valid_num = valid_num + 1 - if valid_num != 0: - kpt_score = kpt_score / valid_num - # rescoring - n_p['score'] = kpt_score * box_score - - if self.soft_nms: - keep = soft_oks_nms( - [img_kpts[i] for i in range(len(img_kpts))], oks_thr) - else: - keep = oks_nms([img_kpts[i] for i in range(len(img_kpts))], - oks_thr) - - if len(keep) == 0: - oks_nmsed_kpts.append(img_kpts) - else: - oks_nmsed_kpts.append([img_kpts[_keep] for _keep in keep]) - - self._write_coco_keypoint_results(oks_nmsed_kpts, res_file) - - info_str = self._do_python_keypoint_eval(res_file) - name_value = OrderedDict(info_str) - - return name_value From ec5a36e2c8c310c3bb1aeee03e5d313f38084bb2 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Thu, 27 Aug 2020 20:03:22 +0800 Subject: [PATCH 22/25] im_ann --> img_ann --- mmpose/datasets/datasets/top_down/topdown_coco_dataset.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index 2afa3619ff..f799c59937 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -156,9 +156,9 @@ def _load_coco_keypoint_annotation_kernel(self, index): Returns: db entry """ - im_ann = self.coco.loadImgs(index)[0] - width = im_ann['width'] - height = im_ann['height'] + img_ann = self.coco.loadImgs(index)[0] + width = img_ann['width'] + height = img_ann['height'] num_joints = self.ann_info['num_joints'] ann_ids = self.coco.getAnnIds(imgIds=index, iscrowd=False) From 46481985179f1ddee9a25e2ecd1aa9267035e3d4 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Fri, 28 Aug 2020 11:38:30 +0800 Subject: [PATCH 23/25] resolve comments --- mmpose/datasets/datasets/bottom_up/bottom_up_coco.py | 8 +++----- mmpose/datasets/datasets/top_down/topdown_aic_dataset.py | 8 +++----- mmpose/datasets/datasets/top_down/topdown_coco_dataset.py | 8 +++----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py index a6c3759fb0..e15c7f4f05 100644 --- a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py +++ b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py @@ -314,8 +314,8 @@ def _coco_keypoint_results_one_category_kernel(self, data_pack): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" - coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(self.coco, coco_dt, 'keypoints') + coco_det = self.coco.loadRes(res_file) + coco_eval = COCOeval(self.coco, coco_det, 'keypoints') coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() @@ -326,8 +326,6 @@ def _do_python_keypoint_eval(self, res_file): 'AR .75', 'AR (M)', 'AR (L)' ] - info_str = [] - for ind, name in enumerate(stats_names): - info_str.append((name, coco_eval.stats[ind])) + info_str = list(zip(stats_names, coco_eval.stats)) return info_str diff --git a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py index 359824813e..92bae23278 100644 --- a/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_aic_dataset.py @@ -108,9 +108,9 @@ def _get_db(self): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" - coco_dt = self.coco.loadRes(res_file) + coco_det = self.coco.loadRes(res_file) coco_eval = COCOeval( - self.coco, coco_dt, 'keypoints', self.sigmas, use_area=False) + self.coco, coco_det, 'keypoints', self.sigmas, use_area=False) coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() @@ -121,8 +121,6 @@ def _do_python_keypoint_eval(self, res_file): 'AR .75', 'AR (M)', 'AR (L)' ] - info_str = [] - for ind, name in enumerate(stats_names): - info_str.append((name, coco_eval.stats[ind])) + info_str = list(zip(stats_names, coco_eval.stats)) return info_str diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index f799c59937..1c96edf1fe 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -400,8 +400,8 @@ def _coco_keypoint_results_one_category_kernel(self, data_pack): def _do_python_keypoint_eval(self, res_file): """Keypoint evaluation using COCOAPI.""" - coco_dt = self.coco.loadRes(res_file) - coco_eval = COCOeval(self.coco, coco_dt, 'keypoints', self.sigmas) + coco_det = self.coco.loadRes(res_file) + coco_eval = COCOeval(self.coco, coco_det, 'keypoints', self.sigmas) coco_eval.params.useSegm = None coco_eval.evaluate() coco_eval.accumulate() @@ -412,8 +412,6 @@ def _do_python_keypoint_eval(self, res_file): 'AR .75', 'AR (M)', 'AR (L)' ] - info_str = [] - for ind, name in enumerate(stats_names): - info_str.append((name, coco_eval.stats[ind])) + info_str = list(zip(stats_names, coco_eval.stats)) return info_str From f32df9a8081a6813cbee467cc03d0b23283a29c0 Mon Sep 17 00:00:00 2001 From: jinsheng Date: Fri, 28 Aug 2020 12:01:08 +0800 Subject: [PATCH 24/25] fix path --- mmpose/datasets/datasets/top_down/topdown_coco_dataset.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index 1c96edf1fe..c710a837db 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -252,7 +252,8 @@ def _load_coco_person_detection_results(self): if det_res['category_id'] != 1: continue - img_name = self.id2name[det_res['image_id']] + image_file = os.path.join(self.img_prefix, + self.id2name[det_res['image_id']]) box = det_res['bbox'] score = det_res['score'] @@ -265,7 +266,7 @@ def _load_coco_person_detection_results(self): joints_3d = np.zeros((num_joints, 3), dtype=np.float32) joints_3d_visible = np.ones((num_joints, 3), dtype=np.float32) kpt_db.append({ - 'image_file': img_name, + 'image_file': image_file, 'center': center, 'scale': scale, 'rotation': 0, From 5a46dfb06b3a27b649cdad464f982042aec6f0ed Mon Sep 17 00:00:00 2001 From: jinsheng Date: Fri, 28 Aug 2020 12:13:24 +0800 Subject: [PATCH 25/25] fix assert --- mmpose/datasets/datasets/bottom_up/bottom_up_coco.py | 8 ++++++-- .../datasets/datasets/top_down/topdown_coco_dataset.py | 8 ++++++-- .../datasets/datasets/top_down/topdown_mpii_dataset.py | 9 ++++++--- .../datasets/top_down/topdown_mpii_trb_dataset.py | 9 +++++++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py index e15c7f4f05..611820aca3 100644 --- a/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py +++ b/mmpose/datasets/datasets/bottom_up/bottom_up_coco.py @@ -202,12 +202,16 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): '2', '0', '1', '7', '/', '0', '0', '0', '0', '0', '0', '3', '9', '7', '1', '3', '3', '.', 'j', 'p', 'g'] res_folder (str): Path of directory to save the results. - metric (str): Metric to be performed. Defaults: 'mAP'. + metric (str | list[str]): Metric to be performed. Defaults: 'mAP'. Returns: name_value (dict): Evaluation results for evaluation metric. """ - assert metric == 'mAP' + metrics = metric if isinstance(metric, list) else [metric] + allowed_metrics = ['mAP'] + for metric in metrics: + if metric not in allowed_metrics: + raise KeyError(f'metric {metric} is not supported') res_file = os.path.join(res_folder, 'result_keypoints.json') diff --git a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py index c710a837db..878ffeb54e 100644 --- a/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py @@ -296,12 +296,16 @@ def evaluate(self, outputs, res_folder, metric='mAP', **kwargs): '2', '0', '1', '7', '/', '0', '0', '0', '0', '0', '0', '3', '9', '7', '1', '3', '3', '.', 'j', 'p', 'g'] res_folder (str): Path of directory to save the results. - metric (str): Metric to be performed. Defaults: 'mAP'. + metric (str | list[str]): Metric to be performed. Defaults: 'mAP'. Returns: name_value (dict): Evaluation results for evaluation metric. """ - assert metric == 'mAP' + metrics = metric if isinstance(metric, list) else [metric] + allowed_metrics = ['mAP'] + for metric in metrics: + if metric not in allowed_metrics: + raise KeyError(f'metric {metric} is not supported') res_file = os.path.join(res_folder, 'result_keypoints.json') diff --git a/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py b/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py index 608efd54b7..f65f1d2e2b 100644 --- a/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_mpii_dataset.py @@ -131,15 +131,18 @@ def evaluate(self, outputs, res_folder, metric='PCKh', **kwargs): image_path(list[str]): For example, ['0', '0', '0', '0', '0', '1', '1', '6', '3', '.', 'j', 'p', 'g'] res_folder(str): Path of directory to save the results. - metric(str): Metrics to be performed. + metric (str | list[str]): Metrics to be performed. Defaults: 'PCKh'. Returns: PCKh for each joint """ - # only PCKh is supported. - assert metric == 'PCKh' + metrics = metric if isinstance(metric, list) else [metric] + allowed_metrics = ['PCKh'] + for metric in metrics: + if metric not in allowed_metrics: + raise KeyError(f'metric {metric} is not supported') preds = np.stack([kpts[0] for kpts, _, _ in outputs]) diff --git a/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py b/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py index c33dd32116..573c579e26 100644 --- a/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py +++ b/mmpose/datasets/datasets/top_down/topdown_mpii_trb_dataset.py @@ -154,14 +154,19 @@ def evaluate(self, outputs, res_folder, metric='PCKh', **kwargs): image_path(list[str]): For example, ['0', '0', '0', '0', '0', '1', '1', '6', '3', '.', 'j', 'p', 'g'] res_folder(str): Path of directory to save the results. - metric(str): Metrics to be performed. + metric (str | list[str]): Metrics to be performed. Defaults: 'PCKh'. Returns: PCKh for each joint """ # only PCKh is supported. - assert metric == 'PCKh' + + metrics = metric if isinstance(metric, list) else [metric] + allowed_metrics = ['PCKh'] + for metric in metrics: + if metric not in allowed_metrics: + raise KeyError(f'metric {metric} is not supported') """Evaluate MPII-TRB keypoint results.""" res_file = os.path.join(res_folder, 'result_keypoints.json')