Initial snapshot: hand motion pipeline (Dyn-HaMR + dex-retargeting + SPIDER)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,75 @@
|
||||
# Demo
|
||||
|
||||
This page provides tutorials about running demos. Please click the caption for more information.
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="resources/demo_coco.gif" width="600px" alt><br>
|
||||
|
||||
[2D human pose demo](docs/2d_human_pose_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/9464825/95552839-00a61080-0a40-11eb-818c-b8dad7307217.gif" width="600px" alt><br>
|
||||
|
||||
[2D human whole-body pose demo](docs/2d_wholebody_pose_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109098558-8c54db00-775c-11eb-8966-85df96b23dc5.gif" width="600px" alt><br>
|
||||
|
||||
[2D hand pose demo](docs/2d_hand_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109144943-ccd44900-779c-11eb-9e9d-8682e7629654.gif" width="600px" alt><br>
|
||||
|
||||
[2D face keypoint demo](docs/2d_face_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/15977946/118820606-02df2000-b8e9-11eb-9984-b9228101e780.gif" width="600px" alt><br>
|
||||
|
||||
[3D human pose demo](docs/3d_human_pose_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109099201-a93dde00-775d-11eb-9624-f9676fc0e478.gif" width="600px" alt><br>
|
||||
|
||||
[2D pose tracking demo](docs/2d_pose_tracking_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/11788150/114201893-4446ec00-9989-11eb-808b-5718c47c7b23.gif" width="600px" alt><br>
|
||||
|
||||
[2D animal_pose demo](docs/2d_animal_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/28900607/121288285-b8fcbf00-c915-11eb-98e4-ba846de12987.gif" width="600px" alt><br>
|
||||
|
||||
[3D hand_pose demo](docs/3d_hand_demo.md)
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/15977946/124059525-ce20c580-da5d-11eb-8e4a-2d96cd31fe9f.gif" width="600px" alt><br>
|
||||
|
||||
[Webcam demo](docs/webcam_demo.md)
|
||||
</div>
|
||||
@@ -0,0 +1,296 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import os.path as osp
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import mmcv
|
||||
import numpy as np
|
||||
from xtcocotools.coco import COCO
|
||||
|
||||
from mmpose.apis import (inference_pose_lifter_model,
|
||||
inference_top_down_pose_model, vis_3d_pose_result)
|
||||
from mmpose.apis.inference import init_pose_model
|
||||
from mmpose.core import SimpleCamera
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def _keypoint_camera_to_world(keypoints,
|
||||
camera_params,
|
||||
image_name=None,
|
||||
dataset='Body3DH36MDataset'):
|
||||
"""Project 3D keypoints from the camera space to the world space.
|
||||
|
||||
Args:
|
||||
keypoints (np.ndarray): 3D keypoints in shape [..., 3]
|
||||
camera_params (dict): Parameters for all cameras.
|
||||
image_name (str): The image name to specify the camera.
|
||||
dataset (str): The dataset type, e.g. Body3DH36MDataset.
|
||||
"""
|
||||
cam_key = None
|
||||
if dataset == 'Body3DH36MDataset':
|
||||
subj, rest = osp.basename(image_name).split('_', 1)
|
||||
_, rest = rest.split('.', 1)
|
||||
camera, rest = rest.split('_', 1)
|
||||
cam_key = (subj, camera)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
camera = SimpleCamera(camera_params[cam_key])
|
||||
keypoints_world = keypoints.copy()
|
||||
keypoints_world[..., :3] = camera.camera_to_world(keypoints[..., :3])
|
||||
|
||||
return keypoints_world
|
||||
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument(
|
||||
'pose_lifter_config',
|
||||
help='Config file for the 2nd stage pose lifter model')
|
||||
parser.add_argument(
|
||||
'pose_lifter_checkpoint',
|
||||
help='Checkpoint file for the 2nd stage pose lifter model')
|
||||
parser.add_argument(
|
||||
'--pose-detector-config',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Config file for the 1st stage 2D pose detector')
|
||||
parser.add_argument(
|
||||
'--pose-detector-checkpoint',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Checkpoint file for the 1st stage 2D pose detector')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument(
|
||||
'--json-file',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Json file containing image and bbox information. Optionally,'
|
||||
'The Json file can also contain 2D pose information. See'
|
||||
'"only-second-stage"')
|
||||
parser.add_argument(
|
||||
'--camera-param-file',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Camera parameter file for converting 3D pose predictions from '
|
||||
' the camera space to to world space. If None, no conversion will be '
|
||||
'applied.')
|
||||
parser.add_argument(
|
||||
'--only-second-stage',
|
||||
action='store_true',
|
||||
help='If true, load 2D pose detection result from the Json file and '
|
||||
'skip the 1st stage. The pose detection model will be ignored.')
|
||||
parser.add_argument(
|
||||
'--rebase-keypoint-height',
|
||||
action='store_true',
|
||||
help='Rebase the predicted 3D pose so its lowest keypoint has a '
|
||||
'height of 0 (landing on the ground). This is useful for '
|
||||
'visualization when the model do not predict the global position '
|
||||
'of the 3D pose.')
|
||||
parser.add_argument(
|
||||
'--show-ground-truth',
|
||||
action='store_true',
|
||||
help='If True, show ground truth if it is available. The ground truth '
|
||||
'should be contained in the annotations in the Json file with the key '
|
||||
'"keypoints_3d" for each instance.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Root of the output visualization images. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device for inference')
|
||||
parser.add_argument('--kpt-thr', type=float, default=0.3)
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
assert args.show or (args.out_img_root != '')
|
||||
|
||||
coco = COCO(args.json_file)
|
||||
|
||||
# First stage: 2D pose detection
|
||||
pose_det_results_list = []
|
||||
if args.only_second_stage:
|
||||
from mmpose.apis.inference import _xywh2xyxy
|
||||
|
||||
print('Stage 1: load 2D pose results from Json file.')
|
||||
for image_id, image in coco.imgs.items():
|
||||
image_name = osp.join(args.img_root, image['file_name'])
|
||||
ann_ids = coco.getAnnIds(image_id)
|
||||
pose_det_results = []
|
||||
for ann_id in ann_ids:
|
||||
ann = coco.anns[ann_id]
|
||||
keypoints = np.array(ann['keypoints']).reshape(-1, 3)
|
||||
keypoints[..., 2] = keypoints[..., 2] >= 1
|
||||
keypoints_3d = np.array(ann['keypoints_3d']).reshape(-1, 4)
|
||||
keypoints_3d[..., 3] = keypoints_3d[..., 3] >= 1
|
||||
bbox = np.array(ann['bbox']).reshape(1, -1)
|
||||
|
||||
pose_det_result = {
|
||||
'image_name': image_name,
|
||||
'bbox': _xywh2xyxy(bbox),
|
||||
'keypoints': keypoints,
|
||||
'keypoints_3d': keypoints_3d
|
||||
}
|
||||
pose_det_results.append(pose_det_result)
|
||||
pose_det_results_list.append(pose_det_results)
|
||||
|
||||
else:
|
||||
print('Stage 1: 2D pose detection.')
|
||||
|
||||
pose_det_model = init_pose_model(
|
||||
args.pose_detector_config,
|
||||
args.pose_detector_checkpoint,
|
||||
device=args.device.lower())
|
||||
|
||||
assert pose_det_model.cfg.model.type == 'TopDown', 'Only "TopDown"' \
|
||||
'model is supported for the 1st stage (2D pose detection)'
|
||||
|
||||
dataset = pose_det_model.cfg.data['test']['type']
|
||||
dataset_info = pose_det_model.cfg.data['test'].get(
|
||||
'dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 '
|
||||
'for details.', DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
img_keys = list(coco.imgs.keys())
|
||||
|
||||
for i in mmcv.track_iter_progress(range(len(img_keys))):
|
||||
# get bounding box annotations
|
||||
image_id = img_keys[i]
|
||||
image = coco.loadImgs(image_id)[0]
|
||||
image_name = osp.join(args.img_root, image['file_name'])
|
||||
ann_ids = coco.getAnnIds(image_id)
|
||||
|
||||
# make person results for single image
|
||||
person_results = []
|
||||
for ann_id in ann_ids:
|
||||
person = {}
|
||||
ann = coco.anns[ann_id]
|
||||
person['bbox'] = ann['bbox']
|
||||
person_results.append(person)
|
||||
|
||||
pose_det_results, _ = inference_top_down_pose_model(
|
||||
pose_det_model,
|
||||
image_name,
|
||||
person_results,
|
||||
bbox_thr=None,
|
||||
format='xywh',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=False,
|
||||
outputs=None)
|
||||
|
||||
for res in pose_det_results:
|
||||
res['image_name'] = image_name
|
||||
pose_det_results_list.append(pose_det_results)
|
||||
|
||||
# Second stage: Pose lifting
|
||||
print('Stage 2: 2D-to-3D pose lifting.')
|
||||
|
||||
pose_lift_model = init_pose_model(
|
||||
args.pose_lifter_config,
|
||||
args.pose_lifter_checkpoint,
|
||||
device=args.device.lower())
|
||||
|
||||
assert pose_lift_model.cfg.model.type == 'PoseLifter', 'Only' \
|
||||
'"PoseLifter" model is supported for the 2nd stage ' \
|
||||
'(2D-to-3D lifting)'
|
||||
dataset = pose_lift_model.cfg.data['test']['type']
|
||||
dataset_info = pose_lift_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
camera_params = None
|
||||
if args.camera_param_file is not None:
|
||||
camera_params = mmcv.load(args.camera_param_file)
|
||||
|
||||
for i, pose_det_results in enumerate(
|
||||
mmcv.track_iter_progress(pose_det_results_list)):
|
||||
# 2D-to-3D pose lifting
|
||||
# Note that the pose_det_results are regarded as a single-frame pose
|
||||
# sequence
|
||||
pose_lift_results = inference_pose_lifter_model(
|
||||
pose_lift_model,
|
||||
pose_results_2d=[pose_det_results],
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
with_track_id=False)
|
||||
|
||||
image_name = pose_det_results[0]['image_name']
|
||||
|
||||
# Pose processing
|
||||
pose_lift_results_vis = []
|
||||
for idx, res in enumerate(pose_lift_results):
|
||||
keypoints_3d = res['keypoints_3d']
|
||||
# project to world space
|
||||
if camera_params is not None:
|
||||
keypoints_3d = _keypoint_camera_to_world(
|
||||
keypoints_3d,
|
||||
camera_params=camera_params,
|
||||
image_name=image_name,
|
||||
dataset=dataset)
|
||||
# rebase height (z-axis)
|
||||
if args.rebase_keypoint_height:
|
||||
keypoints_3d[..., 2] -= np.min(
|
||||
keypoints_3d[..., 2], axis=-1, keepdims=True)
|
||||
res['keypoints_3d'] = keypoints_3d
|
||||
# Add title
|
||||
det_res = pose_det_results[idx]
|
||||
instance_id = det_res.get('track_id', idx)
|
||||
res['title'] = f'Prediction ({instance_id})'
|
||||
pose_lift_results_vis.append(res)
|
||||
# Add ground truth
|
||||
if args.show_ground_truth:
|
||||
if 'keypoints_3d' not in det_res:
|
||||
print('Fail to show ground truth. Please make sure that'
|
||||
' the instance annotations from the Json file'
|
||||
' contain "keypoints_3d".')
|
||||
else:
|
||||
gt = res.copy()
|
||||
gt['keypoints_3d'] = det_res['keypoints_3d']
|
||||
gt['title'] = f'Ground truth ({instance_id})'
|
||||
pose_lift_results_vis.append(gt)
|
||||
|
||||
# Visualization
|
||||
if args.out_img_root is None:
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = osp.join(args.out_img_root, f'vis_{i}.jpg')
|
||||
|
||||
vis_3d_pose_result(
|
||||
pose_lift_model,
|
||||
result=pose_lift_results_vis,
|
||||
img=image_name,
|
||||
dataset_info=dataset_info,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,307 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import copy
|
||||
import os
|
||||
import os.path as osp
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
import mmcv
|
||||
import numpy as np
|
||||
|
||||
from mmpose.apis import (extract_pose_sequence, get_track_id,
|
||||
inference_pose_lifter_model,
|
||||
inference_top_down_pose_model, init_pose_model,
|
||||
process_mmdet_results, vis_3d_pose_result)
|
||||
|
||||
try:
|
||||
from mmdet.apis import inference_detector, init_detector
|
||||
|
||||
has_mmdet = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmdet = False
|
||||
|
||||
|
||||
def covert_keypoint_definition(keypoints, pose_det_dataset, pose_lift_dataset):
|
||||
"""Convert pose det dataset keypoints definition to pose lifter dataset
|
||||
keypoints definition.
|
||||
|
||||
Args:
|
||||
keypoints (ndarray[K, 2 or 3]): 2D keypoints to be transformed.
|
||||
pose_det_dataset, (str): Name of the dataset for 2D pose detector.
|
||||
pose_lift_dataset (str): Name of the dataset for pose lifter model.
|
||||
"""
|
||||
if pose_det_dataset == 'TopDownH36MDataset' and \
|
||||
pose_lift_dataset == 'Body3DH36MDataset':
|
||||
return keypoints
|
||||
elif pose_det_dataset == 'TopDownCocoDataset' and \
|
||||
pose_lift_dataset == 'Body3DH36MDataset':
|
||||
keypoints_new = np.zeros((17, keypoints.shape[1]))
|
||||
# pelvis is in the middle of l_hip and r_hip
|
||||
keypoints_new[0] = (keypoints[11] + keypoints[12]) / 2
|
||||
# thorax is in the middle of l_shoulder and r_shoulder
|
||||
keypoints_new[8] = (keypoints[5] + keypoints[6]) / 2
|
||||
# head is in the middle of l_eye and r_eye
|
||||
keypoints_new[10] = (keypoints[1] + keypoints[2]) / 2
|
||||
# spine is in the middle of thorax and pelvis
|
||||
keypoints_new[7] = (keypoints_new[0] + keypoints_new[8]) / 2
|
||||
# rearrange other keypoints
|
||||
keypoints_new[[1, 2, 3, 4, 5, 6, 9, 11, 12, 13, 14, 15, 16]] = \
|
||||
keypoints[[12, 14, 16, 11, 13, 15, 0, 5, 7, 9, 6, 8, 10]]
|
||||
return keypoints_new
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('det_config', help='Config file for detection')
|
||||
parser.add_argument('det_checkpoint', help='Checkpoint file for detection')
|
||||
parser.add_argument(
|
||||
'pose_detector_config',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Config file for the 1st stage 2D pose detector')
|
||||
parser.add_argument(
|
||||
'pose_detector_checkpoint',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Checkpoint file for the 1st stage 2D pose detector')
|
||||
parser.add_argument(
|
||||
'pose_lifter_config',
|
||||
help='Config file for the 2nd stage pose lifter model')
|
||||
parser.add_argument(
|
||||
'pose_lifter_checkpoint',
|
||||
help='Checkpoint file for the 2nd stage pose lifter model')
|
||||
parser.add_argument(
|
||||
'--video-path', type=str, default='', help='Video path')
|
||||
parser.add_argument(
|
||||
'--rebase-keypoint-height',
|
||||
action='store_true',
|
||||
help='Rebase the predicted 3D pose so its lowest keypoint has a '
|
||||
'height of 0 (landing on the ground). This is useful for '
|
||||
'visualization when the model do not predict the global position '
|
||||
'of the 3D pose.')
|
||||
parser.add_argument(
|
||||
'--norm-pose-2d',
|
||||
action='store_true',
|
||||
help='Scale the bbox (along with the 2D pose) to the average bbox '
|
||||
'scale of the dataset, and move the bbox (along with the 2D pose) to '
|
||||
'the average bbox center of the dataset. This is useful when bbox '
|
||||
'is small, especially in multi-person scenarios.')
|
||||
parser.add_argument(
|
||||
'--num-instances',
|
||||
type=int,
|
||||
default=-1,
|
||||
help='The number of 3D poses to be visualized in every frame. If '
|
||||
'less than 0, it will be set to the number of pose results in the '
|
||||
'first frame.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device for inference')
|
||||
parser.add_argument(
|
||||
'--det-cat-id',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Category id for bounding box detection model')
|
||||
parser.add_argument(
|
||||
'--bbox-thr',
|
||||
type=float,
|
||||
default=0.9,
|
||||
help='Bounding box score threshold')
|
||||
parser.add_argument('--kpt-thr', type=float, default=0.3)
|
||||
parser.add_argument(
|
||||
'--use-oks-tracking', action='store_true', help='Using OKS tracking')
|
||||
parser.add_argument(
|
||||
'--tracking-thr', type=float, default=0.3, help='Tracking threshold')
|
||||
parser.add_argument(
|
||||
'--euro',
|
||||
action='store_true',
|
||||
help='Using One_Euro_Filter for smoothing')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=8,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=2,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_mmdet, 'Please install mmdet to run the demo.'
|
||||
|
||||
args = parser.parse_args()
|
||||
assert args.show or (args.out_video_root != '')
|
||||
assert args.det_config is not None
|
||||
assert args.det_checkpoint is not None
|
||||
|
||||
video = mmcv.VideoReader(args.video_path)
|
||||
assert video.opened, f'Failed to load video file {args.video_path}'
|
||||
|
||||
# First stage: 2D pose detection
|
||||
print('Stage 1: 2D pose detection.')
|
||||
|
||||
person_det_model = init_detector(
|
||||
args.det_config, args.det_checkpoint, device=args.device.lower())
|
||||
|
||||
pose_det_model = init_pose_model(
|
||||
args.pose_detector_config,
|
||||
args.pose_detector_checkpoint,
|
||||
device=args.device.lower())
|
||||
|
||||
assert pose_det_model.cfg.model.type == 'TopDown', 'Only "TopDown"' \
|
||||
'model is supported for the 1st stage (2D pose detection)'
|
||||
|
||||
pose_det_dataset = pose_det_model.cfg.data['test']['type']
|
||||
|
||||
pose_det_results_list = []
|
||||
next_id = 0
|
||||
pose_det_results = []
|
||||
for frame in video:
|
||||
pose_det_results_last = pose_det_results
|
||||
|
||||
# test a single image, the resulting box is (x1, y1, x2, y2)
|
||||
mmdet_results = inference_detector(person_det_model, frame)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_det_results = process_mmdet_results(mmdet_results,
|
||||
args.det_cat_id)
|
||||
|
||||
# make person results for single image
|
||||
pose_det_results, _ = inference_top_down_pose_model(
|
||||
pose_det_model,
|
||||
frame,
|
||||
person_det_results,
|
||||
bbox_thr=args.bbox_thr,
|
||||
format='xyxy',
|
||||
dataset=pose_det_dataset,
|
||||
return_heatmap=False,
|
||||
outputs=None)
|
||||
|
||||
# get track id for each person instance
|
||||
pose_det_results, next_id = get_track_id(
|
||||
pose_det_results,
|
||||
pose_det_results_last,
|
||||
next_id,
|
||||
use_oks=args.use_oks_tracking,
|
||||
tracking_thr=args.tracking_thr,
|
||||
use_one_euro=args.euro,
|
||||
fps=video.fps)
|
||||
|
||||
pose_det_results_list.append(copy.deepcopy(pose_det_results))
|
||||
|
||||
# Second stage: Pose lifting
|
||||
print('Stage 2: 2D-to-3D pose lifting.')
|
||||
|
||||
pose_lift_model = init_pose_model(
|
||||
args.pose_lifter_config,
|
||||
args.pose_lifter_checkpoint,
|
||||
device=args.device.lower())
|
||||
|
||||
assert pose_lift_model.cfg.model.type == 'PoseLifter', \
|
||||
'Only "PoseLifter" model is supported for the 2nd stage ' \
|
||||
'(2D-to-3D lifting)'
|
||||
pose_lift_dataset = pose_lift_model.cfg.data['test']['type']
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
fps = video.fps
|
||||
writer = None
|
||||
|
||||
# convert keypoint definition
|
||||
for pose_det_results in pose_det_results_list:
|
||||
for res in pose_det_results:
|
||||
keypoints = res['keypoints']
|
||||
res['keypoints'] = covert_keypoint_definition(
|
||||
keypoints, pose_det_dataset, pose_lift_dataset)
|
||||
|
||||
# load temporal padding config from model.data_cfg
|
||||
if hasattr(pose_lift_model.cfg, 'test_data_cfg'):
|
||||
data_cfg = pose_lift_model.cfg.test_data_cfg
|
||||
else:
|
||||
data_cfg = pose_lift_model.cfg.data_cfg
|
||||
|
||||
num_instances = args.num_instances
|
||||
for i, pose_det_results in enumerate(
|
||||
mmcv.track_iter_progress(pose_det_results_list)):
|
||||
# extract and pad input pose2d sequence
|
||||
pose_results_2d = extract_pose_sequence(
|
||||
pose_det_results_list,
|
||||
frame_idx=i,
|
||||
causal=data_cfg.causal,
|
||||
seq_len=data_cfg.seq_len,
|
||||
step=data_cfg.seq_frame_interval)
|
||||
# 2D-to-3D pose lifting
|
||||
pose_lift_results = inference_pose_lifter_model(
|
||||
pose_lift_model,
|
||||
pose_results_2d=pose_results_2d,
|
||||
dataset=pose_lift_dataset,
|
||||
with_track_id=True,
|
||||
image_size=video.resolution,
|
||||
norm_pose_2d=args.norm_pose_2d)
|
||||
|
||||
# Pose processing
|
||||
pose_lift_results_vis = []
|
||||
for idx, res in enumerate(pose_lift_results):
|
||||
keypoints_3d = res['keypoints_3d']
|
||||
# exchange y,z-axis, and then reverse the direction of x,z-axis
|
||||
keypoints_3d = keypoints_3d[..., [0, 2, 1]]
|
||||
keypoints_3d[..., 0] = -keypoints_3d[..., 0]
|
||||
keypoints_3d[..., 2] = -keypoints_3d[..., 2]
|
||||
# rebase height (z-axis)
|
||||
if args.rebase_keypoint_height:
|
||||
keypoints_3d[..., 2] -= np.min(
|
||||
keypoints_3d[..., 2], axis=-1, keepdims=True)
|
||||
res['keypoints_3d'] = keypoints_3d
|
||||
# add title
|
||||
det_res = pose_det_results[idx]
|
||||
instance_id = det_res['track_id']
|
||||
res['title'] = f'Prediction ({instance_id})'
|
||||
# only visualize the target frame
|
||||
res['keypoints'] = det_res['keypoints']
|
||||
res['bbox'] = det_res['bbox']
|
||||
res['track_id'] = instance_id
|
||||
pose_lift_results_vis.append(res)
|
||||
|
||||
# Visualization
|
||||
if num_instances < 0:
|
||||
num_instances = len(pose_lift_results_vis)
|
||||
img_vis = vis_3d_pose_result(
|
||||
pose_lift_model,
|
||||
result=pose_lift_results_vis,
|
||||
img=video[i],
|
||||
out_file=None,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
num_instances=num_instances)
|
||||
|
||||
if save_out_video:
|
||||
if writer is None:
|
||||
writer = cv2.VideoWriter(
|
||||
osp.join(args.out_video_root,
|
||||
f'vis_{osp.basename(args.video_path)}'), fourcc,
|
||||
fps, (img_vis.shape[1], img_vis.shape[0]))
|
||||
writer.write(img_vis)
|
||||
|
||||
if save_out_video:
|
||||
writer.release()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,127 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import os.path as osp
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import mmcv
|
||||
|
||||
from mmpose.apis import (inference_bottom_up_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images."""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for detection')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file')
|
||||
parser.add_argument(
|
||||
'--img-path',
|
||||
type=str,
|
||||
help='Path to an image file or a image folder.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default='',
|
||||
help='Root of the output img file. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--pose-nms-thr',
|
||||
type=float,
|
||||
default=0.9,
|
||||
help='OKS threshold for pose NMS')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_img_root != '')
|
||||
|
||||
# prepare image list
|
||||
if osp.isfile(args.img_path):
|
||||
image_list = [args.img_path]
|
||||
elif osp.isdir(args.img_path):
|
||||
image_list = [
|
||||
osp.join(args.img_path, fn) for fn in os.listdir(args.img_path)
|
||||
if fn.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp'))
|
||||
]
|
||||
else:
|
||||
raise ValueError('Image path should be an image or image folder.'
|
||||
f'Got invalid image path: {args.img_path}')
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
assert (dataset == 'BottomUpCocoDataset')
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
# process each image
|
||||
for image_name in mmcv.track_iter_progress(image_list):
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_bottom_up_pose_model(
|
||||
pose_model,
|
||||
image_name,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
pose_nms_thr=args.pose_nms_thr,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
if args.out_img_root == '':
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = os.path.join(
|
||||
args.out_img_root,
|
||||
f'vis_{osp.splitext(osp.basename(image_name))[0]}.jpg')
|
||||
|
||||
# show the results
|
||||
vis_pose_result(
|
||||
pose_model,
|
||||
image_name,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=args.show,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,158 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (get_track_id, inference_bottom_up_pose_model,
|
||||
init_pose_model, vis_pose_tracking_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images."""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.5, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--pose-nms-thr',
|
||||
type=float,
|
||||
default=0.9,
|
||||
help='OKS threshold for pose NMS')
|
||||
parser.add_argument(
|
||||
'--use-oks-tracking', action='store_true', help='Using OKS tracking')
|
||||
parser.add_argument(
|
||||
'--tracking-thr', type=float, default=0.3, help='Tracking threshold')
|
||||
parser.add_argument(
|
||||
'--euro',
|
||||
action='store_true',
|
||||
help='Using One_Euro_Filter for smoothing')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
assert (dataset == 'BottomUpCocoDataset')
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
fps = None
|
||||
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
next_id = 0
|
||||
pose_results = []
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
pose_results_last = pose_results
|
||||
|
||||
pose_results, returned_outputs = inference_bottom_up_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
pose_nms_thr=args.pose_nms_thr,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# get track id for each person instance
|
||||
pose_results, next_id = get_track_id(
|
||||
pose_results,
|
||||
pose_results_last,
|
||||
next_id,
|
||||
use_oks=args.use_oks_tracking,
|
||||
tracking_thr=args.tracking_thr,
|
||||
use_one_euro=args.euro,
|
||||
fps=fps)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_tracking_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,135 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (inference_bottom_up_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images."""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--pose-nms-thr',
|
||||
type=float,
|
||||
default=0.9,
|
||||
help='OKS threshold for pose NMS')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
assert (dataset == 'BottomUpCocoDataset')
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
|
||||
pose_results, returned_outputs = inference_bottom_up_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
pose_nms_thr=args.pose_nms_thr,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,148 @@
|
||||
## 2D Animal Pose Demo
|
||||
|
||||
### 2D Animal Pose Image Demo
|
||||
|
||||
#### Using gt hand bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
*Pose Model Preparation:*
|
||||
The pre-trained pose estimation model can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/topics/animal.html).
|
||||
Take [macaque model](https://download.openmmlab.com/mmpose/animal/resnet/res50_macaque_256x192-98f1dd3a_20210407.pth) as an example:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/macaque/res50_macaque_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/animal/resnet/res50_macaque_256x192-98f1dd3a_20210407.pth \
|
||||
--img-root tests/data/macaque/ --json-file tests/data/macaque/test_macaque.json \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
To run demos on CPU:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/macaque/res50_macaque_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/animal/resnet/res50_macaque_256x192-98f1dd3a_20210407.pth \
|
||||
--img-root tests/data/macaque/ --json-file tests/data/macaque/test_macaque.json \
|
||||
--out-img-root vis_results \
|
||||
--device=cpu
|
||||
```
|
||||
|
||||
### 2D Animal Pose Video Demo
|
||||
|
||||
We also provide video demos to illustrate the results.
|
||||
|
||||
#### Using the full image as input
|
||||
|
||||
If the video is cropped with the object centered in the screen, we can simply use the full image as the model input (without object detection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_full_frame_without_det.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_full_frame_without_det.py \
|
||||
configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/fly/res152_fly_192x192.py \
|
||||
https://download.openmmlab.com/mmpose/animal/resnet/res152_fly_192x192-fcafbd5a_20210407.pth \
|
||||
--video-path demo/resources/<demo_fly_video.avi> \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/114023530-944c8280-98a5-11eb-86b0-5f6d3e232af0.gif" height="140px" alt><br>
|
||||
|
||||
#### Using MMDetection to detect animals
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
**COCO-animals**
|
||||
|
||||
In COCO dataset, there are 80 object categories, including 10 common `animal` categories (15: 'bird', 16: 'cat', 17: 'dog', 18: 'horse', 19: 'sheep', 20: 'cow', 21: 'elephant', 22: 'bear', 23: 'zebra', 24: 'giraffe')
|
||||
For these COCO-animals, please download the COCO pre-trained detection model from [MMDetection Model Zoo](https://mmdetection.readthedocs.io/en/latest/model_zoo.html).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
--det-cat-id ${CATEGORY_ID}
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_2x_coco/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth \
|
||||
configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/horse10/res50_horse10_256x256-split1.py \
|
||||
https://download.openmmlab.com/mmpose/animal/resnet/res50_horse10_256x256_split1-3a3dc37e_20210405.pth \
|
||||
--video-path demo/resources/<demo_horse.mp4> \
|
||||
--out-video-root vis_results \
|
||||
--bbox-thr 0.1 \
|
||||
--kpt-thr 0.4 \
|
||||
--det-cat-id 18
|
||||
```
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/114201893-4446ec00-9989-11eb-808b-5718c47c7b23.gif" height="140px" alt><br>
|
||||
|
||||
**Other Animals**
|
||||
|
||||
For other animals, we have also provided some pre-trained animal detection models (1-class models). Supported models can be found in [det model zoo](/demo/docs/mmdet_modelzoo.md).
|
||||
The pre-trained animal pose estimation model can be found in [pose model zoo](https://mmpose.readthedocs.io/en/latest/topics/animal.html).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--det-cat-id ${CATEGORY_ID}]
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py \
|
||||
https://openmmlab.oss-cn-hangzhou.aliyuncs.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque-e45e36f5_20210409.pth \
|
||||
configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/macaque/res152_macaque_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/animal/resnet/res152_macaque_256x192-c42abc02_20210407.pth \
|
||||
--video-path demo/resources/<demo_macaque.mp4> \
|
||||
--out-video-root vis_results \
|
||||
--bbox-thr 0.5 \
|
||||
--kpt-thr 0.3 \
|
||||
```
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/114205282-b5d46980-998c-11eb-9d6b-85ba47f81252.gif" height="140px" alt><br>
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For 2D animal pose estimation models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [macaque-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/animal/resnet/macaque/res50_macaque_256x192.py#L51).
|
||||
1. set `post_process='default'` in [macaque-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/animal/resnet/macaque/res50_macaque_256x192.py#L52).
|
||||
@@ -0,0 +1,103 @@
|
||||
## 2D Face Keypoint Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109144943-ccd44900-779c-11eb-9e9d-8682e7629654.gif" width="600px" alt><br>
|
||||
|
||||
### 2D Face Image Demo
|
||||
|
||||
#### Using gt face bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
*Face Keypoint Model Preparation:*
|
||||
The pre-trained face keypoint estimation model can be found from [model zoo](https://mmpose.readthedocs.io/en/latest/topics/face.html).
|
||||
Take [aflw model](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth) as an example:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/face/2d_kpt_sview_rgb_img/topdown_heatmap/aflw/hrnetv2_w18_aflw_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth \
|
||||
--img-root tests/data/aflw/ --json-file tests/data/aflw/test_aflw.json \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
To run demos on CPU:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/face/2d_kpt_sview_rgb_img/topdown_heatmap/aflw/hrnetv2_w18_aflw_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth \
|
||||
--img-root tests/data/aflw/ --json-file tests/data/aflw/test_aflw.json \
|
||||
--out-img-root vis_results \
|
||||
--device=cpu
|
||||
```
|
||||
|
||||
#### Using face bounding box detectors
|
||||
|
||||
We provide a demo script to run face detection and face keypoint estimation.
|
||||
|
||||
Please install `face_recognition` before running the demo, by `pip install face_recognition`.
|
||||
For more details, please refer to https://github.com/ageitgey/face_recognition.
|
||||
|
||||
```shell
|
||||
python demo/face_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --img ${IMG_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
```shell
|
||||
python demo/face_img_demo.py \
|
||||
configs/face/2d_kpt_sview_rgb_img/topdown_heatmap/aflw/hrnetv2_w18_aflw_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth \
|
||||
--img-root tests/data/aflw/ \
|
||||
--img image04476.jpg \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
### 2D Face Video Demo
|
||||
|
||||
We also provide a video demo to illustrate the results.
|
||||
|
||||
Please install `face_recognition` before running the demo, by `pip install face_recognition`.
|
||||
For more details, please refer to https://github.com/ageitgey/face_recognition.
|
||||
|
||||
```shell
|
||||
python demo/face_video_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/face_video_demo.py \
|
||||
configs/face/2d_kpt_sview_rgb_img/topdown_heatmap/aflw/hrnetv2_w18_aflw_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth \
|
||||
--video-path https://user-images.githubusercontent.com/87690686/137441355-ec4da09c-3a8f-421b-bee9-b8b26f8c2dd0.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For 2D face keypoint estimation models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [face-hrnetv2_w18](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/face/hrnetv2/aflw/hrnetv2_w18_aflw_256x256.py#L83).
|
||||
1. set `post_process='default'` in [face-hrnetv2_w18](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/face/hrnetv2/aflw/hrnetv2_w18_aflw_256x256.py#L84).
|
||||
@@ -0,0 +1,113 @@
|
||||
## 2D Hand Keypoint Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109098558-8c54db00-775c-11eb-8966-85df96b23dc5.gif" width="600px" alt><br>
|
||||
|
||||
### 2D Hand Image Demo
|
||||
|
||||
#### Using gt hand bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
*Hand Pose Model Preparation:*
|
||||
The pre-trained hand pose estimation model can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/topics/hand%282d%29.html).
|
||||
Take [onehand10k model](https://download.openmmlab.com/mmpose/top_down/resnet/res50_onehand10k_256x256-e67998f6_20200813.pth) as an example:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/hand/2d_kpt_sview_rgb_img/topdown_heatmap/onehand10k/res50_onehand10k_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_onehand10k_256x256-e67998f6_20200813.pth \
|
||||
--img-root tests/data/onehand10k/ --json-file tests/data/onehand10k/test_onehand10k.json \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
To run demos on CPU:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/hand/2d_kpt_sview_rgb_img/topdown_heatmap/onehand10k/res50_onehand10k_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_onehand10k_256x256-e67998f6_20200813.pth \
|
||||
--img-root tests/data/onehand10k/ --json-file tests/data/onehand10k/test_onehand10k.json \
|
||||
--out-img-root vis_results \
|
||||
--device=cpu
|
||||
```
|
||||
|
||||
#### Using mmdet for hand bounding box detection
|
||||
|
||||
We provide a demo script to run mmdet for hand detection, and mmpose for hand pose estimation.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
*Hand Box Model Preparation:* The pre-trained hand box estimation model can be found in [det model zoo](/demo/docs/mmdet_modelzoo.md).
|
||||
|
||||
*Hand Pose Model Preparation:* The pre-trained hand pose estimation model can be downloaded from [pose model zoo](https://mmpose.readthedocs.io/en/latest/topics/hand%282d%29.html).
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --img ${IMG_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py \
|
||||
https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k-dac19597_20201030.pth \
|
||||
configs/hand/2d_kpt_sview_rgb_img/topdown_heatmap/onehand10k/res50_onehand10k_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_onehand10k_256x256-e67998f6_20200813.pth \
|
||||
--img-root tests/data/onehand10k/ \
|
||||
--img 9.jpg \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
### 2D Hand Video Demo
|
||||
|
||||
We also provide a video demo to illustrate the results.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
*Hand Box Model Preparation:* The pre-trained hand box estimation model can be found in [det model zoo](/demo/docs/mmdet_modelzoo.md).
|
||||
|
||||
*Hand Pose Model Preparation:* The pre-trained hand pose estimation model can be found in [pose model zoo](https://mmpose.readthedocs.io/en/latest/topics/hand%282d%29.html).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py \
|
||||
https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k-dac19597_20201030.pth \
|
||||
configs/hand/2d_kpt_sview_rgb_img/topdown_heatmap/onehand10k/res50_onehand10k_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_onehand10k_256x256-e67998f6_20200813.pth \
|
||||
--video-path https://user-images.githubusercontent.com/87690686/137441388-3ea93d26-5445-4184-829e-bf7011def9e4.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For 2D hand pose estimation models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [hand-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/hand/resnet/onehand10k/res50_onehand10k_256x256.py#L56).
|
||||
1. set `post_process='default'` in [hand-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/hand/resnet/onehand10k/res50_onehand10k_256x256.py#L57).
|
||||
@@ -0,0 +1,159 @@
|
||||
## 2D Human Pose Demo
|
||||
|
||||
<img src="https://raw.githubusercontent.com/open-mmlab/mmpose/master/demo/resources/demo_coco.gif" width="600px" alt><br>
|
||||
|
||||
### 2D Human Pose Top-Down Image Demo
|
||||
|
||||
#### Using gt human bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
|
||||
--img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
To run demos on CPU:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
|
||||
--img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
|
||||
--out-img-root vis_results \
|
||||
--device=cpu
|
||||
```
|
||||
|
||||
#### Using mmdet for human bounding box detection
|
||||
|
||||
We provide a demo script to run mmdet for human detection, and mmpose for pose estimation.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --img ${IMG_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
|
||||
--img-root tests/data/coco/ \
|
||||
--img 000000196141.jpg \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
### 2D Human Pose Top-Down Video Demo
|
||||
|
||||
We also provide a video demo to illustrate the results.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
|
||||
--video-path demo/resources/demo.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### 2D Human Pose Bottom-Up Image Demo
|
||||
|
||||
We provide a demo script to test a single image.
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-path ${IMG_PATH}\
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR} --pose-nms-thr ${POSE_NMS_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_img_demo.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/associative_embedding/coco/hrnet_w32_coco_512x512.py \
|
||||
https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth \
|
||||
--img-path tests/data/coco/ \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
### 2D Human Pose Bottom-Up Video Demo
|
||||
|
||||
We also provide a video demo to illustrate the results.
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_video_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR} --pose-nms-thr ${POSE_NMS_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_video_demo.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/associative_embedding/coco/hrnet_w32_coco_512x512.py \
|
||||
https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth \
|
||||
--video-path demo/resources/demo.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For top-down models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [topdown-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/top_down/resnet/coco/res50_coco_256x192.py#L51).
|
||||
1. set `post_process='default'` in [topdown-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/top_down/resnet/coco/res50_coco_256x192.py#L52).
|
||||
1. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/latest/model_zoo.html).
|
||||
|
||||
For bottom-up models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L80).
|
||||
1. set `adjust=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L78).
|
||||
1. set `refine=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L79).
|
||||
1. use smaller input image size in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L39).
|
||||
@@ -0,0 +1,101 @@
|
||||
## 2D Pose Tracking Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/11788150/109099201-a93dde00-775d-11eb-9624-f9676fc0e478.gif" width="600px" alt><br>
|
||||
|
||||
### 2D Top-Down Video Human Pose Tracking Demo
|
||||
|
||||
We provide a video demo to illustrate the pose tracking results.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_pose_tracking_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
[--use-oks-tracking --tracking-thr ${TRACKING_THR} --euro]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_pose_tracking_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth \
|
||||
--video-path demo/resources/demo.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### 2D Top-Down Video Human Pose Tracking Demo with MMTracking
|
||||
|
||||
MMTracking is an open source video perception toolbox based on PyTorch for tracking related tasks.
|
||||
Here we show how to utilize MMTracking and MMPose to achieve human pose tracking.
|
||||
|
||||
Assume that you have already installed [mmtracking](https://github.com/open-mmlab/mmtracking).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmtracking.py \
|
||||
${MMTRACKING_CONFIG_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_pose_tracking_demo_with_mmtracking.py \
|
||||
demo/mmtracking_cfg/tracktor_faster-rcnn_r50_fpn_4e_mot17-private.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/res50_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth \
|
||||
--video-path demo/resources/demo.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### 2D Bottom-Up Video Human Pose Tracking Demo
|
||||
|
||||
We also provide a pose tracking demo with bottom-up pose estimation methods.
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_pose_tracking_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR} --pose-nms-thr ${POSE_NMS_THR}]
|
||||
[--use-oks-tracking --tracking-thr ${TRACKING_THR} --euro]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/bottom_up_pose_tracking_demo.py \
|
||||
configs/body/2d_kpt_sview_rgb_img/associative_embedding/coco/hrnet_w32_coco_512x512.py \
|
||||
https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth \
|
||||
--video-path demo/resources/demo.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For top-down models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [topdown-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/top_down/resnet/coco/res50_coco_256x192.py#L51).
|
||||
1. set `post_process='default'` in [topdown-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/top_down/resnet/coco/res50_coco_256x192.py#L52).
|
||||
1. use faster human detector or human tracker, see [MMDetection](https://mmdetection.readthedocs.io/en/latest/model_zoo.html) or [MMTracking](https://mmtracking.readthedocs.io/en/latest/model_zoo.html).
|
||||
|
||||
For bottom-up models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L80).
|
||||
1. set `adjust=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L78).
|
||||
1. set `refine=False` in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L79).
|
||||
1. use smaller input image size in [AE-res50](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/bottom_up/resnet/coco/res50_coco_512x512.py#L39).
|
||||
@@ -0,0 +1,106 @@
|
||||
## 2D Human Whole-Body Pose Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/9464825/95552839-00a61080-0a40-11eb-818c-b8dad7307217.gif" width="600px" alt><br>
|
||||
|
||||
### 2D Human Whole-Body Pose Top-Down Image Demo
|
||||
|
||||
#### Using gt human bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --json-file ${JSON_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/wholebody/2d_kpt_sview_rgb_img/topdown_heatmap/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \
|
||||
--img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
To run demos on CPU:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo.py \
|
||||
configs/wholebody/2d_kpt_sview_rgb_img/topdown_heatmap/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \
|
||||
--img-root tests/data/coco/ --json-file tests/data/coco/test_coco.json \
|
||||
--out-img-root vis_results \
|
||||
--device=cpu
|
||||
```
|
||||
|
||||
#### Using mmdet for human bounding box detection
|
||||
|
||||
We provide a demo script to run mmdet for human detection, and mmpose for pose estimation.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--img-root ${IMG_ROOT} --img ${IMG_FILE} \
|
||||
--out-img-root ${OUTPUT_DIR} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_img_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/wholebody/2d_kpt_sview_rgb_img/topdown_heatmap/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \
|
||||
--img-root tests/data/coco/ \
|
||||
--img 000000196141.jpg \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
|
||||
### 2D Human Whole-Body Pose Top-Down Video Demo
|
||||
|
||||
We also provide a video demo to illustrate the results.
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--video-path ${VIDEO_FILE} \
|
||||
--out-video-root ${OUTPUT_VIDEO_ROOT} \
|
||||
[--show --device ${GPU_ID or CPU}] \
|
||||
[--bbox-thr ${BBOX_SCORE_THR} --kpt-thr ${KPT_SCORE_THR}]
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```shell
|
||||
python demo/top_down_video_demo_with_mmdet.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/wholebody/2d_kpt_sview_rgb_img/topdown_heatmap/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \
|
||||
--video-path https://user-images.githubusercontent.com/87690686/137440639-fb08603d-9a35-474e-b65f-46b5c06b68d6.mp4 \
|
||||
--out-video-root vis_results
|
||||
```
|
||||
|
||||
### Speed Up Inference
|
||||
|
||||
Some tips to speed up MMPose inference:
|
||||
|
||||
For top-down models, try to edit the config file. For example,
|
||||
|
||||
1. set `flip_test=False` in [pose_hrnet_w48_dark+](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/wholebody/darkpose/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py#L80).
|
||||
1. set `post_process='default'` in [pose_hrnet_w48_dark+](https://github.com/open-mmlab/mmpose/tree/e1ec589884235bee875c89102170439a991f8450/configs/wholebody/darkpose/coco-wholebody/hrnet_w48_coco_wholebody_384x288_dark_plus.py#L81).
|
||||
1. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/latest/model_zoo.html).
|
||||
@@ -0,0 +1,28 @@
|
||||
## 3D Mesh Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/28900607/124615414-d33fa380-dea7-11eb-9ec4-a01d0931e028.gif" width="600px" alt><br>
|
||||
|
||||
### 3D Mesh Recovery Demo
|
||||
|
||||
We provide a demo script to recover human 3D mesh from a single image.
|
||||
|
||||
```shell
|
||||
python demo/mesh_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--json-file ${JSON_FILE} \
|
||||
--img-root ${IMG_ROOT} \
|
||||
[--show] \
|
||||
[--device ${GPU_ID or CPU}] \
|
||||
[--out-img-root ${OUTPUT_DIR}]
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
python demo/mesh_img_demo.py \
|
||||
configs/body/3d_mesh_sview_rgb_img/hmr/mixed/res50_mixed_224x224.py \
|
||||
https://download.openmmlab.com/mmpose/mesh/hmr/hmr_mesh_224x224-c21e8229_20201015.pth \
|
||||
--json-file tests/data/h36m/h36m_coco.json \
|
||||
--img-root tests/data/h36m \
|
||||
--out-img-root vis_results
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
## 3D Hand Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/28900607/121288285-b8fcbf00-c915-11eb-98e4-ba846de12987.gif" width="600px" alt><br>
|
||||
|
||||
### 3D Hand Estimation Image Demo
|
||||
|
||||
#### Using gt hand bounding boxes as input
|
||||
|
||||
We provide a demo script to test a single image, given gt json file.
|
||||
|
||||
```shell
|
||||
python demo/interhand3d_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \
|
||||
--json-file ${JSON_FILE} \
|
||||
--img-root ${IMG_ROOT} \
|
||||
[--camera-param-file ${CAMERA_PARAM_FILE}] \
|
||||
[--gt-joints-file ${GT_JOINTS_FILE}]\
|
||||
[--show] \
|
||||
[--device ${GPU_ID or CPU}] \
|
||||
[--out-img-root ${OUTPUT_DIR}] \
|
||||
[--rebase-keypoint-height] \
|
||||
[--show-ground-truth]
|
||||
```
|
||||
|
||||
Example with gt keypoints and camera parameters:
|
||||
|
||||
```shell
|
||||
python demo/interhand3d_img_demo.py \
|
||||
configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3d_all_256x256-b9c1cf4c_20210506.pth \
|
||||
--json-file tests/data/interhand2.6m/test_interhand2.6m_data.json \
|
||||
--img-root tests/data/interhand2.6m \
|
||||
--camera-param-file tests/data/interhand2.6m/test_interhand2.6m_camera.json \
|
||||
--gt-joints-file tests/data/interhand2.6m/test_interhand2.6m_joint_3d.json \
|
||||
--out-img-root vis_results \
|
||||
--rebase-keypoint-height \
|
||||
--show-ground-truth
|
||||
```
|
||||
|
||||
Example without gt keypoints and camera parameters:
|
||||
|
||||
```shell
|
||||
python demo/interhand3d_img_demo.py \
|
||||
configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py \
|
||||
https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3d_all_256x256-b9c1cf4c_20210506.pth \
|
||||
--json-file tests/data/interhand2.6m/test_interhand2.6m_data.json \
|
||||
--img-root tests/data/interhand2.6m \
|
||||
--out-img-root vis_results \
|
||||
--rebase-keypoint-height
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
## 3D Human Pose Demo
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/15977946/118820606-02df2000-b8e9-11eb-9984-b9228101e780.gif" width="600px" alt><br>
|
||||
|
||||
### 3D Human Pose Two-stage Estimation Image Demo
|
||||
|
||||
#### Using ground truth 2D poses as the 1st stage (pose detection) result, and inference the 2nd stage (2D-to-3D lifting)
|
||||
|
||||
We provide a demo script to test on single images with a given ground-truth Json file.
|
||||
|
||||
```shell
|
||||
python demo/body3d_two_stage_img_demo.py \
|
||||
${MMPOSE_CONFIG_FILE_3D} \
|
||||
${MMPOSE_CHECKPOINT_FILE_3D} \
|
||||
--json-file ${JSON_FILE} \
|
||||
--img-root ${IMG_ROOT} \
|
||||
--only-second-stage \
|
||||
[--show] \
|
||||
[--device ${GPU_ID or CPU}] \
|
||||
[--out-img-root ${OUTPUT_DIR}] \
|
||||
[--rebase-keypoint-height] \
|
||||
[--show-ground-truth]
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
python demo/body3d_two_stage_img_demo.py \
|
||||
configs/body/3d_kpt_sview_rgb_img/pose_lift/h36m/simplebaseline3d_h36m.py \
|
||||
https://download.openmmlab.com/mmpose/body3d/simple_baseline/simple3Dbaseline_h36m-f0ad73a4_20210419.pth \
|
||||
--json-file tests/data/h36m/h36m_coco.json \
|
||||
--img-root tests/data/h36m \
|
||||
--camera-param-file tests/data/h36m/cameras.pkl \
|
||||
--only-second-stage \
|
||||
--out-img-root vis_results \
|
||||
--rebase-keypoint-height \
|
||||
--show-ground-truth
|
||||
```
|
||||
|
||||
### 3D Human Pose Two-stage Estimation Video Demo
|
||||
|
||||
#### Using mmdet for human bounding box detection and top-down model for the 1st stage (2D pose detection), and inference the 2nd stage (2D-to-3D lifting)
|
||||
|
||||
Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).
|
||||
|
||||
```shell
|
||||
python demo/body3d_two_stage_video_demo.py \
|
||||
${MMDET_CONFIG_FILE} \
|
||||
${MMDET_CHECKPOINT_FILE} \
|
||||
${MMPOSE_CONFIG_FILE_2D} \
|
||||
${MMPOSE_CHECKPOINT_FILE_2D} \
|
||||
${MMPOSE_CONFIG_FILE_3D} \
|
||||
${MMPOSE_CHECKPOINT_FILE_3D} \
|
||||
--video-path ${VIDEO_PATH} \
|
||||
[--rebase-keypoint-height] \
|
||||
[--norm-pose-2d] \
|
||||
[--num-poses-vis NUM_POSES_VIS] \
|
||||
[--show] \
|
||||
[--out-video-root ${OUT_VIDEO_ROOT}] \
|
||||
[--device ${GPU_ID or CPU}] \
|
||||
[--det-cat-id DET_CAT_ID] \
|
||||
[--bbox-thr BBOX_THR] \
|
||||
[--kpt-thr KPT_THR] \
|
||||
[--use-oks-tracking] \
|
||||
[--tracking-thr TRACKING_THR] \
|
||||
[--euro] \
|
||||
[--radius RADIUS] \
|
||||
[--thickness THICKNESS]
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```shell
|
||||
python demo/body3d_two_stage_video_demo.py \
|
||||
demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py \
|
||||
https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
|
||||
configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w48_coco_256x192.py \
|
||||
https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \
|
||||
configs/body/3d_kpt_sview_rgb_vid/video_pose_lift/h36m/videopose3d_h36m_243frames_fullconv_supervised_cpn_ft.py \
|
||||
https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth \
|
||||
--video-path demo/resources/<demo_body3d>.mp4 \
|
||||
--out-video-root vis_results \
|
||||
--rebase-keypoint-height
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
## Pre-trained Detection Models
|
||||
|
||||
### Human Bounding Box Detection Models
|
||||
|
||||
For human bounding box detection models, please download from [MMDetection Model Zoo](https://mmdetection.readthedocs.io/en/latest/model_zoo.html).
|
||||
MMDetection provides 80-class COCO-pretrained models, which already includes the `person` category.
|
||||
|
||||
### Hand Bounding Box Detection Models
|
||||
|
||||
For hand bounding box detection, we simply train our hand box models on onehand10k dataset using MMDetection.
|
||||
|
||||
#### Hand detection results on OneHand10K test set
|
||||
|
||||
| Arch | Box AP | ckpt | log |
|
||||
| :-------------- | :-----------: | :------: | :------: |
|
||||
| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.817 | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k-dac19597_20201030.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k_20201030.log.json) |
|
||||
|
||||
### Animal Bounding Box Detection Models
|
||||
|
||||
#### COCO animals
|
||||
|
||||
In COCO dataset, there are 80 object categories, including 10 common `animal` categories (16: 'bird', 17: 'cat', 18: 'dog', 19: 'horse', 20: 'sheep', 21: 'cow', 22: 'elephant', 23: 'bear', 24: 'zebra', 25: 'giraffe')
|
||||
For animals in the categories, please download from [MMDetection Model Zoo](https://mmdetection.readthedocs.io/en/latest/model_zoo.html).
|
||||
|
||||
#### Macaque detection results on MacaquePose test set
|
||||
|
||||
| Arch | Box AP | ckpt | log |
|
||||
| :-------------- | :-----------: | :------: | :------: |
|
||||
| [Faster_R-CNN_Res50-FPN-1class](/demo/mmdetection_cfg/faster_rcnn_r50_fpn_1class.py) | 0.840 | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque-f64f2812_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque_20210409.log.json) |
|
||||
| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.879 | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque-e45e36f5_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque_20210409.log.json) |
|
||||
@@ -0,0 +1,49 @@
|
||||
## Webcam Demo
|
||||
|
||||
We provide a webcam demo tool which integrartes detection and 2D pose estimation for humans and animals. You can simply run the following command:
|
||||
|
||||
```python
|
||||
python demo/webcam_demo.py
|
||||
```
|
||||
|
||||
It will launch a window to display the webcam video steam with detection and pose estimation results:
|
||||
|
||||
<div align="center">
|
||||
<img src="https://user-images.githubusercontent.com/15977946/124059525-ce20c580-da5d-11eb-8e4a-2d96cd31fe9f.gif" width="600px" alt><br>
|
||||
</div>
|
||||
|
||||
### Usage Tips
|
||||
|
||||
- **Which model is used in the demo tool?**
|
||||
|
||||
Please check the following default arguments in the script. You can also choose other models from the [MMDetection Model Zoo](https://github.com/open-mmlab/mmdetection/blob/master/docs/model_zoo.md) and [MMPose Model Zoo](https://mmpose.readthedocs.io/en/latest/modelzoo.html#) or use your own models.
|
||||
|
||||
| Model | Arguments |
|
||||
| :--: | :-- |
|
||||
| Detection | `--det-config`, `--det-checkpoint` |
|
||||
| Human Pose | `--human-pose-config`, `--human-pose-checkpoint` |
|
||||
| Animal Pose | `--animal-pose-config`, `--animal-pose-checkpoint` |
|
||||
|
||||
- **Can this tool run without GPU?**
|
||||
|
||||
Yes, you can set `--device=cpu` and the model inference will be performed on CPU. Of course, this may cause a low inference FPS compared to using GPU devices.
|
||||
|
||||
- **Why there is time delay between the pose visualization and the video?**
|
||||
|
||||
The video I/O and model inference are running asynchronously and the latter usually takes more time for a single frame. To allevidate the time delay, you can:
|
||||
|
||||
1. set `--display-delay=MILLISECONDS` to defer the video stream, according to the inference delay shown at the top left corner. Or,
|
||||
|
||||
2. set `--synchronous-mode` to force video stream being aligned with inference results. This may reduce the video display FPS.
|
||||
|
||||
- **Can this tool process video files?**
|
||||
|
||||
Yes. You can set `--cam-id=VIDEO_FILE_PATH` to run the demo tool in offline mode on a video file. Note that `--synchronous-mode` should be set in this case.
|
||||
|
||||
- **How to enable/disable the special effects?**
|
||||
|
||||
The special effects can be enabled/disabled at launch time by setting arguments like `--bugeye`, `--sunglasses`, *etc*. You can also toggle the effects by keyboard shortcuts like `b`, `s` when the tool starts.
|
||||
|
||||
- **What if my computer doesn't have a camera?**
|
||||
|
||||
You can use a smart phone as a webcam with apps like [Camo](https://reincubate.com/camo/) or [DroidCam](https://www.dev47apps.com/).
|
||||
@@ -0,0 +1,140 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
import face_recognition
|
||||
has_face_det = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_face_det = False
|
||||
|
||||
|
||||
def process_face_det_results(face_det_results):
|
||||
"""Process det results, and return a list of bboxes.
|
||||
|
||||
:param face_det_results: (top, right, bottom and left)
|
||||
:return: a list of detected bounding boxes (x,y,x,y)-format
|
||||
"""
|
||||
|
||||
person_results = []
|
||||
for bbox in face_det_results:
|
||||
person = {}
|
||||
# left, top, right, bottom
|
||||
person['bbox'] = [bbox[3], bbox[0], bbox[1], bbox[2]]
|
||||
person_results.append(person)
|
||||
|
||||
return person_results
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument('--img', type=str, default='', help='Image file')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default='',
|
||||
help='root of the output img file. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_face_det, 'Please install face_recognition to run the demo. ' \
|
||||
'"pip install face_recognition", For more details, ' \
|
||||
'see https://github.com/ageitgey/face_recognition'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_img_root != '')
|
||||
assert args.img != ''
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
image_name = os.path.join(args.img_root, args.img)
|
||||
|
||||
# test a single image, the resulting box is (top, right, bottom and left)
|
||||
image = face_recognition.load_image_file(image_name)
|
||||
face_det_results = face_recognition.face_locations(image)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
face_results = process_face_det_results(face_det_results)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
image_name,
|
||||
face_results,
|
||||
bbox_thr=None,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
if args.out_img_root == '':
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = os.path.join(args.out_img_root, f'vis_{args.img}')
|
||||
|
||||
# show the results
|
||||
vis_pose_result(
|
||||
pose_model,
|
||||
image_name,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=args.show,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,167 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
import face_recognition
|
||||
has_face_det = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_face_det = False
|
||||
|
||||
|
||||
def process_face_det_results(face_det_results):
|
||||
"""Process det results, and return a list of bboxes.
|
||||
|
||||
:param face_det_results: (top, right, bottom and left)
|
||||
:return: a list of detected bounding boxes (x,y,x,y)-format
|
||||
"""
|
||||
|
||||
person_results = []
|
||||
for bbox in face_det_results:
|
||||
person = {}
|
||||
# left, top, right, bottom
|
||||
person['bbox'] = [bbox[3], bbox[0], bbox[1], bbox[2]]
|
||||
person_results.append(person)
|
||||
|
||||
return person_results
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_face_det, 'Please install face_recognition to run the demo. '\
|
||||
'"pip install face_recognition", For more details, '\
|
||||
'see https://github.com/ageitgey/face_recognition'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
|
||||
face_det_results = face_recognition.face_locations(
|
||||
cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
|
||||
face_results = process_face_det_results(face_det_results)
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
face_results,
|
||||
bbox_thr=None,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,258 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import os.path as osp
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import mmcv
|
||||
import numpy as np
|
||||
from xtcocotools.coco import COCO
|
||||
|
||||
from mmpose.apis import inference_interhand_3d_model, vis_3d_pose_result
|
||||
from mmpose.apis.inference import init_pose_model
|
||||
from mmpose.core import SimpleCamera
|
||||
|
||||
|
||||
def _transform_interhand_camera_param(interhand_camera_param):
|
||||
"""Transform the camera parameters in interhand2.6m dataset to the format
|
||||
of SimpleCamera.
|
||||
|
||||
Args:
|
||||
interhand_camera_param (dict): camera parameters including:
|
||||
- camrot: 3x3, camera rotation matrix (world-to-camera)
|
||||
- campos: 3x1, camera location in world space
|
||||
- focal: 2x1, camera focal length
|
||||
- princpt: 2x1, camera center
|
||||
|
||||
Returns:
|
||||
param (dict): camera parameters including:
|
||||
- R: 3x3, camera rotation matrix (camera-to-world)
|
||||
- T: 3x1, camera translation (camera-to-world)
|
||||
- f: 2x1, camera focal length
|
||||
- c: 2x1, camera center
|
||||
"""
|
||||
camera_param = {}
|
||||
camera_param['R'] = np.array(interhand_camera_param['camrot']).T
|
||||
camera_param['T'] = np.array(interhand_camera_param['campos'])[:, None]
|
||||
camera_param['f'] = np.array(interhand_camera_param['focal'])[:, None]
|
||||
camera_param['c'] = np.array(interhand_camera_param['princpt'])[:, None]
|
||||
return camera_param
|
||||
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose network')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument(
|
||||
'--json-file',
|
||||
type=str,
|
||||
default='',
|
||||
help='Json file containing image info.')
|
||||
parser.add_argument(
|
||||
'--camera-param-file',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Camera parameter file for converting 3D pose predictions from '
|
||||
' the pixel space to camera space. If None, keypoints in pixel space'
|
||||
'will be visualized')
|
||||
parser.add_argument(
|
||||
'--gt-joints-file',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Optional argument. Ground truth 3D keypoint parameter file. '
|
||||
'If None, gt keypoints will not be shown and keypoints in pixel '
|
||||
'space will be visualized.')
|
||||
parser.add_argument(
|
||||
'--rebase-keypoint-height',
|
||||
action='store_true',
|
||||
help='Rebase the predicted 3D pose so its lowest keypoint has a '
|
||||
'height of 0 (landing on the ground). This is useful for '
|
||||
'visualization when the model do not predict the global position '
|
||||
'of the 3D pose.')
|
||||
parser.add_argument(
|
||||
'--show-ground-truth',
|
||||
action='store_true',
|
||||
help='If True, show ground truth keypoint if it is available.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Root of the output visualization images. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
assert args.show or (args.out_img_root != '')
|
||||
|
||||
coco = COCO(args.json_file)
|
||||
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
|
||||
# load camera parameters
|
||||
camera_params = None
|
||||
if args.camera_param_file is not None:
|
||||
camera_params = mmcv.load(args.camera_param_file)
|
||||
# load ground truth joints parameters
|
||||
gt_joint_params = None
|
||||
if args.gt_joints_file is not None:
|
||||
gt_joint_params = mmcv.load(args.gt_joints_file)
|
||||
|
||||
# load hand bounding boxes
|
||||
det_results_list = []
|
||||
for image_id, image in coco.imgs.items():
|
||||
image_name = osp.join(args.img_root, image['file_name'])
|
||||
|
||||
ann_ids = coco.getAnnIds(image_id)
|
||||
det_results = []
|
||||
|
||||
capture_key = str(image['capture'])
|
||||
camera_key = image['camera']
|
||||
frame_idx = image['frame_idx']
|
||||
|
||||
for ann_id in ann_ids:
|
||||
ann = coco.anns[ann_id]
|
||||
if camera_params is not None:
|
||||
camera_param = {
|
||||
key: camera_params[capture_key][key][camera_key]
|
||||
for key in camera_params[capture_key].keys()
|
||||
}
|
||||
camera_param = _transform_interhand_camera_param(camera_param)
|
||||
else:
|
||||
camera_param = None
|
||||
if gt_joint_params is not None:
|
||||
joint_param = gt_joint_params[capture_key][str(frame_idx)]
|
||||
gt_joint = np.concatenate([
|
||||
np.array(joint_param['world_coord']),
|
||||
np.array(joint_param['joint_valid'])
|
||||
],
|
||||
axis=-1)
|
||||
else:
|
||||
gt_joint = None
|
||||
|
||||
det_result = {
|
||||
'image_name': image_name,
|
||||
'bbox': ann['bbox'], # bbox format is 'xywh'
|
||||
'camera_param': camera_param,
|
||||
'keypoints_3d_gt': gt_joint
|
||||
}
|
||||
det_results.append(det_result)
|
||||
det_results_list.append(det_results)
|
||||
|
||||
for i, det_results in enumerate(
|
||||
mmcv.track_iter_progress(det_results_list)):
|
||||
|
||||
image_name = det_results[0]['image_name']
|
||||
|
||||
pose_results = inference_interhand_3d_model(
|
||||
pose_model, image_name, det_results, dataset=dataset)
|
||||
|
||||
# Post processing
|
||||
pose_results_vis = []
|
||||
for idx, res in enumerate(pose_results):
|
||||
keypoints_3d = res['keypoints_3d']
|
||||
# normalize kpt score
|
||||
if keypoints_3d[:, 3].max() > 1:
|
||||
keypoints_3d[:, 3] /= 255
|
||||
# get 2D keypoints in pixel space
|
||||
res['keypoints'] = keypoints_3d[:, [0, 1, 3]]
|
||||
|
||||
# For model-predicted keypoints, channel 0 and 1 are coordinates
|
||||
# in pixel space, and channel 2 is the depth (in mm) relative
|
||||
# to root joints.
|
||||
# If both camera parameter and absolute depth of root joints are
|
||||
# provided, we can transform keypoint to camera space for better
|
||||
# visualization.
|
||||
camera_param = res['camera_param']
|
||||
keypoints_3d_gt = res['keypoints_3d_gt']
|
||||
if camera_param is not None and keypoints_3d_gt is not None:
|
||||
# build camera model
|
||||
camera = SimpleCamera(camera_param)
|
||||
# transform gt joints from world space to camera space
|
||||
keypoints_3d_gt[:, :3] = camera.world_to_camera(
|
||||
keypoints_3d_gt[:, :3])
|
||||
|
||||
# transform relative depth to absolute depth
|
||||
keypoints_3d[:21, 2] += keypoints_3d_gt[20, 2]
|
||||
keypoints_3d[21:, 2] += keypoints_3d_gt[41, 2]
|
||||
|
||||
# transform keypoints from pixel space to camera space
|
||||
keypoints_3d[:, :3] = camera.pixel_to_camera(
|
||||
keypoints_3d[:, :3])
|
||||
|
||||
# rotate the keypoint to make z-axis correspondent to height
|
||||
# for better visualization
|
||||
vis_R = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])
|
||||
keypoints_3d[:, :3] = keypoints_3d[:, :3] @ vis_R
|
||||
if keypoints_3d_gt is not None:
|
||||
keypoints_3d_gt[:, :3] = keypoints_3d_gt[:, :3] @ vis_R
|
||||
|
||||
# rebase height (z-axis)
|
||||
if args.rebase_keypoint_height:
|
||||
valid = keypoints_3d[..., 3] > 0
|
||||
keypoints_3d[..., 2] -= np.min(
|
||||
keypoints_3d[valid, 2], axis=-1, keepdims=True)
|
||||
res['keypoints_3d'] = keypoints_3d
|
||||
res['keypoints_3d_gt'] = keypoints_3d_gt
|
||||
|
||||
# Add title
|
||||
instance_id = res.get('track_id', idx)
|
||||
res['title'] = f'Prediction ({instance_id})'
|
||||
pose_results_vis.append(res)
|
||||
# Add ground truth
|
||||
if args.show_ground_truth:
|
||||
if keypoints_3d_gt is None:
|
||||
print('Fail to show ground truth. Please make sure that'
|
||||
' gt-joints-file is provided.')
|
||||
else:
|
||||
gt = res.copy()
|
||||
if args.rebase_keypoint_height:
|
||||
valid = keypoints_3d_gt[..., 3] > 0
|
||||
keypoints_3d_gt[..., 2] -= np.min(
|
||||
keypoints_3d_gt[valid, 2], axis=-1, keepdims=True)
|
||||
gt['keypoints_3d'] = keypoints_3d_gt
|
||||
gt['title'] = f'Ground truth ({instance_id})'
|
||||
pose_results_vis.append(gt)
|
||||
|
||||
# Visualization
|
||||
if args.out_img_root is None:
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = osp.join(args.out_img_root, f'vis_{i}.jpg')
|
||||
|
||||
vis_3d_pose_result(
|
||||
pose_model,
|
||||
result=pose_results_vis,
|
||||
img=det_results[0]['image_name'],
|
||||
out_file=out_file,
|
||||
dataset=dataset,
|
||||
show=args.show,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,93 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from xtcocotools.coco import COCO
|
||||
|
||||
from mmpose.apis import (inference_mesh_model, init_pose_model,
|
||||
vis_3d_mesh_result)
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Require the json_file containing boxes.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for detection')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument(
|
||||
'--json-file',
|
||||
type=str,
|
||||
default='',
|
||||
help='Json file containing image info.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default='',
|
||||
help='Root of the output img file. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_img_root != '')
|
||||
|
||||
coco = COCO(args.json_file)
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
|
||||
img_keys = list(coco.imgs.keys())
|
||||
|
||||
# process each image
|
||||
for i in range(len(img_keys)):
|
||||
# get bounding box annotations
|
||||
image_id = img_keys[i]
|
||||
image = coco.loadImgs(image_id)[0]
|
||||
image_name = os.path.join(args.img_root, image['file_name'])
|
||||
ann_ids = coco.getAnnIds(image_id)
|
||||
|
||||
# make person bounding boxes
|
||||
person_results = []
|
||||
for ann_id in ann_ids:
|
||||
person = {}
|
||||
ann = coco.anns[ann_id]
|
||||
# bbox format is 'xywh'
|
||||
person['bbox'] = ann['bbox']
|
||||
person_results.append(person)
|
||||
|
||||
# test a single image, with a list of bboxes
|
||||
pose_results = inference_mesh_model(
|
||||
pose_model,
|
||||
image_name,
|
||||
person_results,
|
||||
bbox_thr=None,
|
||||
format='xywh',
|
||||
dataset=dataset)
|
||||
|
||||
if args.out_img_root == '':
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = os.path.join(args.out_img_root, f'vis_{i}.jpg')
|
||||
|
||||
vis_3d_mesh_result(
|
||||
pose_model,
|
||||
pose_results,
|
||||
image_name,
|
||||
show=args.show,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Vendored
+255
@@ -0,0 +1,255 @@
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
step=[16, 19])
|
||||
total_epochs = 20
|
||||
# model settings
|
||||
model = dict(
|
||||
type='CascadeRCNN',
|
||||
pretrained='open-mmlab://resnext101_64x4d',
|
||||
backbone=dict(
|
||||
type='ResNeXt',
|
||||
depth=101,
|
||||
groups=64,
|
||||
base_width=4,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
style='pytorch'),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[.0, .0, .0, .0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0]),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='CascadeRoIHead',
|
||||
num_stages=3,
|
||||
stage_loss_weights=[1, 0.5, 0.25],
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=[
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
|
||||
loss_weight=1.0)),
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.05, 0.05, 0.1, 0.1]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
|
||||
loss_weight=1.0)),
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.033, 0.033, 0.067, 0.067]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))
|
||||
]),
|
||||
# model training and testing settings
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=0,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=2000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=[
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.6,
|
||||
neg_iou_thr=0.6,
|
||||
min_pos_iou=0.6,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.7,
|
||||
min_pos_iou=0.7,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)
|
||||
]),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100)))
|
||||
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_train2017.json',
|
||||
img_prefix=f'{data_root}/train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline))
|
||||
evaluation = dict(interval=1, metric='bbox')
|
||||
Vendored
+256
@@ -0,0 +1,256 @@
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
step=[16, 19])
|
||||
total_epochs = 20
|
||||
|
||||
# model settings
|
||||
model = dict(
|
||||
type='CascadeRCNN',
|
||||
pretrained='open-mmlab://resnext101_64x4d',
|
||||
backbone=dict(
|
||||
type='ResNeXt',
|
||||
depth=101,
|
||||
groups=64,
|
||||
base_width=4,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
style='pytorch'),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[.0, .0, .0, .0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0]),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='CascadeRoIHead',
|
||||
num_stages=3,
|
||||
stage_loss_weights=[1, 0.5, 0.25],
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=[
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=80,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
|
||||
loss_weight=1.0)),
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=80,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.05, 0.05, 0.1, 0.1]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
|
||||
loss_weight=1.0)),
|
||||
dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=80,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.033, 0.033, 0.067, 0.067]),
|
||||
reg_class_agnostic=True,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))
|
||||
]),
|
||||
# model training and testing settings
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=0,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=2000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=[
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.6,
|
||||
neg_iou_thr=0.6,
|
||||
min_pos_iou=0.6,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.7,
|
||||
min_pos_iou=0.7,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)
|
||||
]),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100)))
|
||||
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_train2017.json',
|
||||
img_prefix=f'{data_root}/train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline))
|
||||
evaluation = dict(interval=1, metric='bbox')
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
step=[8, 11])
|
||||
total_epochs = 12
|
||||
|
||||
model = dict(
|
||||
type='FasterRCNN',
|
||||
pretrained='torchvision://resnet50',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
norm_eval=True,
|
||||
style='pytorch'),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[.0, .0, .0, .0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0]),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='StandardRoIHead',
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2]),
|
||||
reg_class_agnostic=False,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0))),
|
||||
# model training and testing settings
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100)
|
||||
# soft-nms is also supported for rcnn testing
|
||||
# e.g., nms=dict(type='soft_nms', iou_threshold=0.5, min_score=0.05)
|
||||
))
|
||||
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_train2017.json',
|
||||
img_prefix=f'{data_root}/train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline))
|
||||
evaluation = dict(interval=1, metric='bbox')
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
step=[8, 11])
|
||||
total_epochs = 12
|
||||
|
||||
model = dict(
|
||||
type='FasterRCNN',
|
||||
pretrained='torchvision://resnet50',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
norm_eval=True,
|
||||
style='pytorch'),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[.0, .0, .0, .0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0]),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='StandardRoIHead',
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=80,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0., 0., 0., 0.],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2]),
|
||||
reg_class_agnostic=False,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0))),
|
||||
# model training and testing settings
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100)
|
||||
# soft-nms is also supported for rcnn testing
|
||||
# e.g., nms=dict(type='soft_nms', iou_threshold=0.5, min_score=0.05)
|
||||
))
|
||||
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_train2017.json',
|
||||
img_prefix=f'{data_root}/train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline))
|
||||
evaluation = dict(interval=1, metric='bbox')
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
model = dict(
|
||||
type='MaskRCNN',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
norm_eval=True,
|
||||
style='pytorch',
|
||||
init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0]),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='StandardRoIHead',
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=80,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2]),
|
||||
reg_class_agnostic=False,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),
|
||||
loss_bbox=dict(type='L1Loss', loss_weight=1.0)),
|
||||
mask_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(type='RoIAlign', output_size=14, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
mask_head=dict(
|
||||
type='FCNMaskHead',
|
||||
num_convs=4,
|
||||
in_channels=256,
|
||||
conv_out_channels=256,
|
||||
num_classes=80,
|
||||
loss_mask=dict(
|
||||
type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))),
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
mask_size=28,
|
||||
pos_weight=-1,
|
||||
debug=False)),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100,
|
||||
mask_thr_binary=0.5)))
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco/'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks'])
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='Collect', keys=['img'])
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type='CocoDataset',
|
||||
ann_file='data/coco/annotations/instances_train2017.json',
|
||||
img_prefix='data/coco/train2017/',
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True, with_mask=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(
|
||||
type='Collect',
|
||||
keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks'])
|
||||
]),
|
||||
val=dict(
|
||||
type='CocoDataset',
|
||||
ann_file='data/coco/annotations/instances_val2017.json',
|
||||
img_prefix='data/coco/val2017/',
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='Collect', keys=['img'])
|
||||
])
|
||||
]),
|
||||
test=dict(
|
||||
type='CocoDataset',
|
||||
ann_file='data/coco/annotations/instances_val2017.json',
|
||||
img_prefix='data/coco/val2017/',
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='Collect', keys=['img'])
|
||||
])
|
||||
]))
|
||||
evaluation = dict(metric=['bbox', 'segm'])
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
step=[16, 22])
|
||||
runner = dict(type='EpochBasedRunner', max_epochs=24)
|
||||
checkpoint_config = dict(interval=1)
|
||||
log_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])
|
||||
custom_hooks = [dict(type='NumClassCheckHook')]
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
Vendored
+216
@@ -0,0 +1,216 @@
|
||||
# =========================================================
|
||||
# from 'mmdetection/configs/_base_/default_runtime.py'
|
||||
# =========================================================
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
custom_hooks = [dict(type='NumClassCheckHook')]
|
||||
# =========================================================
|
||||
|
||||
# =========================================================
|
||||
# from 'mmdetection/configs/_base_/datasets/coco_detection.py'
|
||||
# =========================================================
|
||||
# dataset settings
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco/'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1333, 800),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=data_root + 'annotations/instances_train2017.json',
|
||||
img_prefix=data_root + 'train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=data_root + 'annotations/instances_val2017.json',
|
||||
img_prefix=data_root + 'val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=data_root + 'annotations/instances_val2017.json',
|
||||
img_prefix=data_root + 'val2017/',
|
||||
pipeline=test_pipeline))
|
||||
evaluation = dict(interval=1, metric='bbox')
|
||||
# =========================================================
|
||||
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
|
||||
model = dict(
|
||||
type='SingleStageDetector',
|
||||
backbone=dict(
|
||||
type='MobileNetV2',
|
||||
out_indices=(4, 7),
|
||||
norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),
|
||||
init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),
|
||||
neck=dict(
|
||||
type='SSDNeck',
|
||||
in_channels=(96, 1280),
|
||||
out_channels=(96, 1280, 512, 256, 256, 128),
|
||||
level_strides=(2, 2, 2, 2),
|
||||
level_paddings=(1, 1, 1, 1),
|
||||
l2_norm_scale=None,
|
||||
use_depthwise=True,
|
||||
norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),
|
||||
act_cfg=dict(type='ReLU6'),
|
||||
init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),
|
||||
bbox_head=dict(
|
||||
type='SSDHead',
|
||||
in_channels=(96, 1280, 512, 256, 256, 128),
|
||||
num_classes=80,
|
||||
use_depthwise=True,
|
||||
norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),
|
||||
act_cfg=dict(type='ReLU6'),
|
||||
init_cfg=dict(type='Normal', layer='Conv2d', std=0.001),
|
||||
|
||||
# set anchor size manually instead of using the predefined
|
||||
# SSD300 setting.
|
||||
anchor_generator=dict(
|
||||
type='SSDAnchorGenerator',
|
||||
scale_major=False,
|
||||
strides=[16, 32, 64, 107, 160, 320],
|
||||
ratios=[[2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]],
|
||||
min_sizes=[48, 100, 150, 202, 253, 304],
|
||||
max_sizes=[100, 150, 202, 253, 304, 320]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[.0, .0, .0, .0],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2])),
|
||||
# model training and testing settings
|
||||
train_cfg=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.,
|
||||
ignore_iof_thr=-1,
|
||||
gt_max_assign_all=False),
|
||||
smoothl1_beta=1.,
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
neg_pos_ratio=3,
|
||||
debug=False),
|
||||
test_cfg=dict(
|
||||
nms_pre=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.45),
|
||||
min_bbox_size=0,
|
||||
score_thr=0.02,
|
||||
max_per_img=200))
|
||||
cudnn_benchmark = True
|
||||
|
||||
# dataset settings
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco/'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile', to_float32=True),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(
|
||||
type='PhotoMetricDistortion',
|
||||
brightness_delta=32,
|
||||
contrast_range=(0.5, 1.5),
|
||||
saturation_range=(0.5, 1.5),
|
||||
hue_delta=18),
|
||||
dict(
|
||||
type='Expand',
|
||||
mean=img_norm_cfg['mean'],
|
||||
to_rgb=img_norm_cfg['to_rgb'],
|
||||
ratio_range=(1, 4)),
|
||||
dict(
|
||||
type='MinIoURandomCrop',
|
||||
min_ious=(0.1, 0.3, 0.5, 0.7, 0.9),
|
||||
min_crop_size=0.3),
|
||||
dict(type='Resize', img_scale=(320, 320), keep_ratio=False),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Pad', size_divisor=320),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(320, 320),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=False),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=320),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='Collect', keys=['img']),
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=24,
|
||||
workers_per_gpu=4,
|
||||
train=dict(
|
||||
_delete_=True,
|
||||
type='RepeatDataset', # use RepeatDataset to speed up training
|
||||
times=5,
|
||||
dataset=dict(
|
||||
type=dataset_type,
|
||||
ann_file=data_root + 'annotations/instances_train2017.json',
|
||||
img_prefix=data_root + 'train2017/',
|
||||
pipeline=train_pipeline)),
|
||||
val=dict(pipeline=test_pipeline),
|
||||
test=dict(pipeline=test_pipeline))
|
||||
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.015, momentum=0.9, weight_decay=4.0e-5)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='CosineAnnealing',
|
||||
warmup='linear',
|
||||
warmup_iters=500,
|
||||
warmup_ratio=0.001,
|
||||
min_lr=0)
|
||||
runner = dict(type='EpochBasedRunner', max_epochs=120)
|
||||
|
||||
# Avoid evaluation and saving weights too frequently
|
||||
evaluation = dict(interval=5, metric='bbox')
|
||||
checkpoint_config = dict(interval=5)
|
||||
custom_hooks = [
|
||||
dict(type='NumClassCheckHook'),
|
||||
dict(type='CheckInvalidLossHook', interval=50, priority='VERY_LOW')
|
||||
]
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
# model settings
|
||||
model = dict(
|
||||
type='YOLOV3',
|
||||
pretrained='open-mmlab://darknet53',
|
||||
backbone=dict(type='Darknet', depth=53, out_indices=(3, 4, 5)),
|
||||
neck=dict(
|
||||
type='YOLOV3Neck',
|
||||
num_scales=3,
|
||||
in_channels=[1024, 512, 256],
|
||||
out_channels=[512, 256, 128]),
|
||||
bbox_head=dict(
|
||||
type='YOLOV3Head',
|
||||
num_classes=80,
|
||||
in_channels=[512, 256, 128],
|
||||
out_channels=[1024, 512, 256],
|
||||
anchor_generator=dict(
|
||||
type='YOLOAnchorGenerator',
|
||||
base_sizes=[[(116, 90), (156, 198), (373, 326)],
|
||||
[(30, 61), (62, 45), (59, 119)],
|
||||
[(10, 13), (16, 30), (33, 23)]],
|
||||
strides=[32, 16, 8]),
|
||||
bbox_coder=dict(type='YOLOBBoxCoder'),
|
||||
featmap_strides=[32, 16, 8],
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=True,
|
||||
loss_weight=1.0,
|
||||
reduction='sum'),
|
||||
loss_conf=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=True,
|
||||
loss_weight=1.0,
|
||||
reduction='sum'),
|
||||
loss_xy=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=True,
|
||||
loss_weight=2.0,
|
||||
reduction='sum'),
|
||||
loss_wh=dict(type='MSELoss', loss_weight=2.0, reduction='sum')),
|
||||
# training and testing settings
|
||||
train_cfg=dict(
|
||||
assigner=dict(
|
||||
type='GridAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0)),
|
||||
test_cfg=dict(
|
||||
nms_pre=1000,
|
||||
min_bbox_size=0,
|
||||
score_thr=0.05,
|
||||
conf_thr=0.005,
|
||||
nms=dict(type='nms', iou_threshold=0.45),
|
||||
max_per_img=100))
|
||||
# dataset settings
|
||||
dataset_type = 'CocoDataset'
|
||||
data_root = 'data/coco'
|
||||
img_norm_cfg = dict(mean=[0, 0, 0], std=[255., 255., 255.], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadImageFromFile', to_float32=True),
|
||||
dict(type='LoadAnnotations', with_bbox=True),
|
||||
dict(type='PhotoMetricDistortion'),
|
||||
dict(
|
||||
type='Expand',
|
||||
mean=img_norm_cfg['mean'],
|
||||
to_rgb=img_norm_cfg['to_rgb'],
|
||||
ratio_range=(1, 2)),
|
||||
dict(
|
||||
type='MinIoURandomCrop',
|
||||
min_ious=(0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
|
||||
min_crop_size=0.3),
|
||||
dict(type='Resize', img_scale=(320, 320), keep_ratio=True),
|
||||
dict(type='RandomFlip', flip_ratio=0.5),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(320, 320),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(type='Normalize', **img_norm_cfg),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='DefaultFormatBundle'),
|
||||
dict(type='Collect', keys=['img'])
|
||||
])
|
||||
]
|
||||
data = dict(
|
||||
samples_per_gpu=8,
|
||||
workers_per_gpu=4,
|
||||
train=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_train2017.json',
|
||||
img_prefix=f'{data_root}/train2017/',
|
||||
pipeline=train_pipeline),
|
||||
val=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline),
|
||||
test=dict(
|
||||
type=dataset_type,
|
||||
ann_file=f'{data_root}/annotations/instances_val2017.json',
|
||||
img_prefix=f'{data_root}/val2017/',
|
||||
pipeline=test_pipeline))
|
||||
# optimizer
|
||||
optimizer = dict(type='SGD', lr=0.001, momentum=0.9, weight_decay=0.0005)
|
||||
optimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2))
|
||||
# learning policy
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=2000, # same as burn-in in darknet
|
||||
warmup_ratio=0.1,
|
||||
step=[218, 246])
|
||||
# runtime settings
|
||||
runner = dict(type='EpochBasedRunner', max_epochs=273)
|
||||
evaluation = dict(interval=1, metric=['bbox'])
|
||||
|
||||
checkpoint_config = dict(interval=1)
|
||||
# yapf:disable
|
||||
log_config = dict(
|
||||
interval=50,
|
||||
hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
# dict(type='TensorboardLoggerHook')
|
||||
])
|
||||
# yapf:enable
|
||||
custom_hooks = [dict(type='NumClassCheckHook')]
|
||||
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
model = dict(
|
||||
detector=dict(
|
||||
type='FasterRCNN',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
norm_eval=True,
|
||||
style='pytorch',
|
||||
init_cfg=dict(
|
||||
type='Pretrained', checkpoint='torchvision://resnet50')),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0],
|
||||
clip_border=False),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(
|
||||
type='SmoothL1Loss', beta=0.1111111111111111,
|
||||
loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='StandardRoIHead',
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(
|
||||
type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2],
|
||||
clip_border=False),
|
||||
reg_class_agnostic=False,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', loss_weight=1.0))),
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100)),
|
||||
init_cfg=dict(
|
||||
type='Pretrained',
|
||||
checkpoint='https://download.openmmlab.com/mmtracking/'
|
||||
'mot/faster_rcnn/faster-rcnn_r50_fpn_4e_mot17-half-64ee2ed4.pth')),
|
||||
type='DeepSORT',
|
||||
motion=dict(type='KalmanFilter', center_only=False),
|
||||
reid=dict(
|
||||
type='BaseReID',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(3, ),
|
||||
style='pytorch'),
|
||||
neck=dict(type='GlobalAveragePooling', kernel_size=(8, 4), stride=1),
|
||||
head=dict(
|
||||
type='LinearReIDHead',
|
||||
num_fcs=1,
|
||||
in_channels=2048,
|
||||
fc_channels=1024,
|
||||
out_channels=128,
|
||||
num_classes=380,
|
||||
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
|
||||
loss_pairwise=dict(
|
||||
type='TripletLoss', margin=0.3, loss_weight=1.0),
|
||||
norm_cfg=dict(type='BN1d'),
|
||||
act_cfg=dict(type='ReLU')),
|
||||
init_cfg=dict(
|
||||
type='Pretrained',
|
||||
checkpoint='https://download.openmmlab.com/mmtracking/'
|
||||
'mot/reid/tracktor_reid_r50_iter25245-a452f51f.pth')),
|
||||
tracker=dict(
|
||||
type='SortTracker',
|
||||
obj_score_thr=0.5,
|
||||
reid=dict(
|
||||
num_samples=10,
|
||||
img_scale=(256, 128),
|
||||
img_norm_cfg=None,
|
||||
match_score_thr=2.0),
|
||||
match_iou_thr=0.5,
|
||||
momentums=None,
|
||||
num_tentatives=2,
|
||||
num_frames_retain=100))
|
||||
dataset_type = 'MOTChallengeDataset'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadMultiImagesFromFile', to_float32=True),
|
||||
dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),
|
||||
dict(
|
||||
type='SeqResize',
|
||||
img_scale=(1088, 1088),
|
||||
share_params=True,
|
||||
ratio_range=(0.8, 1.2),
|
||||
keep_ratio=True,
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqPhotoMetricDistortion', share_params=True),
|
||||
dict(
|
||||
type='SeqRandomCrop',
|
||||
share_params=False,
|
||||
crop_size=(1088, 1088),
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),
|
||||
dict(
|
||||
type='SeqNormalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='SeqPad', size_divisor=32),
|
||||
dict(type='MatchInstances', skip_nomatch=True),
|
||||
dict(
|
||||
type='VideoCollect',
|
||||
keys=[
|
||||
'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',
|
||||
'gt_instance_ids'
|
||||
]),
|
||||
dict(type='SeqDefaultFormatBundle', ref_prefix='ref')
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]
|
||||
data_root = 'data/MOT17/'
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type='MOTChallengeDataset',
|
||||
visibility_thr=-1,
|
||||
ann_file='data/MOT17/annotations/half-train_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=dict(
|
||||
num_ref_imgs=1,
|
||||
frame_range=10,
|
||||
filter_key_img=True,
|
||||
method='uniform'),
|
||||
pipeline=[
|
||||
dict(type='LoadMultiImagesFromFile', to_float32=True),
|
||||
dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),
|
||||
dict(
|
||||
type='SeqResize',
|
||||
img_scale=(1088, 1088),
|
||||
share_params=True,
|
||||
ratio_range=(0.8, 1.2),
|
||||
keep_ratio=True,
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqPhotoMetricDistortion', share_params=True),
|
||||
dict(
|
||||
type='SeqRandomCrop',
|
||||
share_params=False,
|
||||
crop_size=(1088, 1088),
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),
|
||||
dict(
|
||||
type='SeqNormalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='SeqPad', size_divisor=32),
|
||||
dict(type='MatchInstances', skip_nomatch=True),
|
||||
dict(
|
||||
type='VideoCollect',
|
||||
keys=[
|
||||
'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',
|
||||
'gt_instance_ids'
|
||||
]),
|
||||
dict(type='SeqDefaultFormatBundle', ref_prefix='ref')
|
||||
]),
|
||||
val=dict(
|
||||
type='MOTChallengeDataset',
|
||||
ann_file='data/MOT17/annotations/half-val_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=None,
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]),
|
||||
test=dict(
|
||||
type='MOTChallengeDataset',
|
||||
ann_file='data/MOT17/annotations/half-val_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=None,
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]))
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
checkpoint_config = dict(interval=1)
|
||||
log_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=100,
|
||||
warmup_ratio=0.01,
|
||||
step=[3])
|
||||
total_epochs = 4
|
||||
evaluation = dict(metric=['bbox', 'track'], interval=1)
|
||||
search_metrics = ['MOTA', 'IDF1', 'FN', 'FP', 'IDs', 'MT', 'ML']
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
model = dict(
|
||||
detector=dict(
|
||||
type='FasterRCNN',
|
||||
pretrained='torchvision://resnet50',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(0, 1, 2, 3),
|
||||
frozen_stages=1,
|
||||
norm_cfg=dict(type='BN', requires_grad=True),
|
||||
norm_eval=True,
|
||||
style='pytorch'),
|
||||
neck=dict(
|
||||
type='FPN',
|
||||
in_channels=[256, 512, 1024, 2048],
|
||||
out_channels=256,
|
||||
num_outs=5),
|
||||
rpn_head=dict(
|
||||
type='RPNHead',
|
||||
in_channels=256,
|
||||
feat_channels=256,
|
||||
anchor_generator=dict(
|
||||
type='AnchorGenerator',
|
||||
scales=[8],
|
||||
ratios=[0.5, 1.0, 2.0],
|
||||
strides=[4, 8, 16, 32, 64]),
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[1.0, 1.0, 1.0, 1.0],
|
||||
clip_border=False),
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),
|
||||
loss_bbox=dict(
|
||||
type='SmoothL1Loss', beta=0.1111111111111111,
|
||||
loss_weight=1.0)),
|
||||
roi_head=dict(
|
||||
type='StandardRoIHead',
|
||||
bbox_roi_extractor=dict(
|
||||
type='SingleRoIExtractor',
|
||||
roi_layer=dict(
|
||||
type='RoIAlign', output_size=7, sampling_ratio=0),
|
||||
out_channels=256,
|
||||
featmap_strides=[4, 8, 16, 32]),
|
||||
bbox_head=dict(
|
||||
type='Shared2FCBBoxHead',
|
||||
in_channels=256,
|
||||
fc_out_channels=1024,
|
||||
roi_feat_size=7,
|
||||
num_classes=1,
|
||||
bbox_coder=dict(
|
||||
type='DeltaXYWHBBoxCoder',
|
||||
target_means=[0.0, 0.0, 0.0, 0.0],
|
||||
target_stds=[0.1, 0.1, 0.2, 0.2],
|
||||
clip_border=False),
|
||||
reg_class_agnostic=False,
|
||||
loss_cls=dict(
|
||||
type='CrossEntropyLoss',
|
||||
use_sigmoid=False,
|
||||
loss_weight=1.0),
|
||||
loss_bbox=dict(type='SmoothL1Loss', loss_weight=1.0))),
|
||||
train_cfg=dict(
|
||||
rpn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.7,
|
||||
neg_iou_thr=0.3,
|
||||
min_pos_iou=0.3,
|
||||
match_low_quality=True,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=256,
|
||||
pos_fraction=0.5,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=False),
|
||||
allowed_border=-1,
|
||||
pos_weight=-1,
|
||||
debug=False),
|
||||
rpn_proposal=dict(
|
||||
nms_pre=2000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
assigner=dict(
|
||||
type='MaxIoUAssigner',
|
||||
pos_iou_thr=0.5,
|
||||
neg_iou_thr=0.5,
|
||||
min_pos_iou=0.5,
|
||||
match_low_quality=False,
|
||||
ignore_iof_thr=-1),
|
||||
sampler=dict(
|
||||
type='RandomSampler',
|
||||
num=512,
|
||||
pos_fraction=0.25,
|
||||
neg_pos_ub=-1,
|
||||
add_gt_as_proposals=True),
|
||||
pos_weight=-1,
|
||||
debug=False)),
|
||||
test_cfg=dict(
|
||||
rpn=dict(
|
||||
nms_pre=1000,
|
||||
max_per_img=1000,
|
||||
nms=dict(type='nms', iou_threshold=0.7),
|
||||
min_bbox_size=0),
|
||||
rcnn=dict(
|
||||
score_thr=0.05,
|
||||
nms=dict(type='nms', iou_threshold=0.5),
|
||||
max_per_img=100))),
|
||||
type='Tracktor',
|
||||
pretrains=dict(
|
||||
detector='https://download.openmmlab.com/mmtracking/'
|
||||
'mot/faster_rcnn/faster-rcnn_r50_fpn_4e_mot17-ffa52ae7.pth',
|
||||
reid='https://download.openmmlab.com/mmtracking/mot/'
|
||||
'reid/reid_r50_6e_mot17-4bf6b63d.pth'),
|
||||
reid=dict(
|
||||
type='BaseReID',
|
||||
backbone=dict(
|
||||
type='ResNet',
|
||||
depth=50,
|
||||
num_stages=4,
|
||||
out_indices=(3, ),
|
||||
style='pytorch'),
|
||||
neck=dict(type='GlobalAveragePooling', kernel_size=(8, 4), stride=1),
|
||||
head=dict(
|
||||
type='LinearReIDHead',
|
||||
num_fcs=1,
|
||||
in_channels=2048,
|
||||
fc_channels=1024,
|
||||
out_channels=128,
|
||||
num_classes=378,
|
||||
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
|
||||
loss_pairwise=dict(
|
||||
type='TripletLoss', margin=0.3, loss_weight=1.0),
|
||||
norm_cfg=dict(type='BN1d'),
|
||||
act_cfg=dict(type='ReLU'))),
|
||||
motion=dict(
|
||||
type='CameraMotionCompensation',
|
||||
warp_mode='cv2.MOTION_EUCLIDEAN',
|
||||
num_iters=100,
|
||||
stop_eps=1e-05),
|
||||
tracker=dict(
|
||||
type='TracktorTracker',
|
||||
obj_score_thr=0.5,
|
||||
regression=dict(
|
||||
obj_score_thr=0.5,
|
||||
nms=dict(type='nms', iou_threshold=0.6),
|
||||
match_iou_thr=0.3),
|
||||
reid=dict(
|
||||
num_samples=10,
|
||||
img_scale=(256, 128),
|
||||
img_norm_cfg=None,
|
||||
match_score_thr=2.0,
|
||||
match_iou_thr=0.2),
|
||||
momentums=None,
|
||||
num_frames_retain=10))
|
||||
dataset_type = 'MOTChallengeDataset'
|
||||
img_norm_cfg = dict(
|
||||
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
|
||||
train_pipeline = [
|
||||
dict(type='LoadMultiImagesFromFile', to_float32=True),
|
||||
dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),
|
||||
dict(
|
||||
type='SeqResize',
|
||||
img_scale=(1088, 1088),
|
||||
share_params=True,
|
||||
ratio_range=(0.8, 1.2),
|
||||
keep_ratio=True,
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqPhotoMetricDistortion', share_params=True),
|
||||
dict(
|
||||
type='SeqRandomCrop',
|
||||
share_params=False,
|
||||
crop_size=(1088, 1088),
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),
|
||||
dict(
|
||||
type='SeqNormalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='SeqPad', size_divisor=32),
|
||||
dict(type='MatchInstances', skip_nomatch=True),
|
||||
dict(
|
||||
type='VideoCollect',
|
||||
keys=[
|
||||
'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',
|
||||
'gt_instance_ids'
|
||||
]),
|
||||
dict(type='SeqDefaultFormatBundle', ref_prefix='ref')
|
||||
]
|
||||
test_pipeline = [
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]
|
||||
data_root = 'data/MOT17/'
|
||||
data = dict(
|
||||
samples_per_gpu=2,
|
||||
workers_per_gpu=2,
|
||||
train=dict(
|
||||
type='MOTChallengeDataset',
|
||||
visibility_thr=-1,
|
||||
ann_file='data/MOT17/annotations/train_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=dict(
|
||||
num_ref_imgs=1,
|
||||
frame_range=10,
|
||||
filter_key_img=True,
|
||||
method='uniform'),
|
||||
pipeline=[
|
||||
dict(type='LoadMultiImagesFromFile', to_float32=True),
|
||||
dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),
|
||||
dict(
|
||||
type='SeqResize',
|
||||
img_scale=(1088, 1088),
|
||||
share_params=True,
|
||||
ratio_range=(0.8, 1.2),
|
||||
keep_ratio=True,
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqPhotoMetricDistortion', share_params=True),
|
||||
dict(
|
||||
type='SeqRandomCrop',
|
||||
share_params=False,
|
||||
crop_size=(1088, 1088),
|
||||
bbox_clip_border=False),
|
||||
dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),
|
||||
dict(
|
||||
type='SeqNormalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='SeqPad', size_divisor=32),
|
||||
dict(type='MatchInstances', skip_nomatch=True),
|
||||
dict(
|
||||
type='VideoCollect',
|
||||
keys=[
|
||||
'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',
|
||||
'gt_instance_ids'
|
||||
]),
|
||||
dict(type='SeqDefaultFormatBundle', ref_prefix='ref')
|
||||
]),
|
||||
val=dict(
|
||||
type='MOTChallengeDataset',
|
||||
ann_file='data/MOT17/annotations/train_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=None,
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]),
|
||||
test=dict(
|
||||
type='MOTChallengeDataset',
|
||||
ann_file='data/MOT17/annotations/train_cocoformat.json',
|
||||
img_prefix='data/MOT17/train',
|
||||
ref_img_sampler=None,
|
||||
pipeline=[
|
||||
dict(type='LoadImageFromFile'),
|
||||
dict(
|
||||
type='MultiScaleFlipAug',
|
||||
img_scale=(1088, 1088),
|
||||
flip=False,
|
||||
transforms=[
|
||||
dict(type='Resize', keep_ratio=True),
|
||||
dict(type='RandomFlip'),
|
||||
dict(
|
||||
type='Normalize',
|
||||
mean=[123.675, 116.28, 103.53],
|
||||
std=[58.395, 57.12, 57.375],
|
||||
to_rgb=True),
|
||||
dict(type='Pad', size_divisor=32),
|
||||
dict(type='ImageToTensor', keys=['img']),
|
||||
dict(type='VideoCollect', keys=['img'])
|
||||
])
|
||||
]))
|
||||
optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)
|
||||
optimizer_config = dict(grad_clip=None)
|
||||
checkpoint_config = dict(interval=1)
|
||||
log_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])
|
||||
dist_params = dict(backend='nccl')
|
||||
log_level = 'INFO'
|
||||
load_from = None
|
||||
resume_from = None
|
||||
workflow = [('train', 1)]
|
||||
lr_config = dict(
|
||||
policy='step',
|
||||
warmup='linear',
|
||||
warmup_iters=100,
|
||||
warmup_ratio=0.01,
|
||||
step=[3])
|
||||
total_epochs = 4
|
||||
evaluation = dict(metric=['bbox', 'track'], interval=1)
|
||||
search_metrics = ['MOTA', 'IDF1', 'FN', 'FP', 'IDs', 'MT', 'ML']
|
||||
test_set = 'train'
|
||||
@@ -0,0 +1,129 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from xtcocotools.coco import COCO
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Require the json_file containing boxes.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for detection')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument(
|
||||
'--json-file',
|
||||
type=str,
|
||||
default='',
|
||||
help='Json file containing image info.')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default='',
|
||||
help='Root of the output img file. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_img_root != '')
|
||||
|
||||
coco = COCO(args.json_file)
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
img_keys = list(coco.imgs.keys())
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
# process each image
|
||||
for i in range(len(img_keys)):
|
||||
# get bounding box annotations
|
||||
image_id = img_keys[i]
|
||||
image = coco.loadImgs(image_id)[0]
|
||||
image_name = os.path.join(args.img_root, image['file_name'])
|
||||
ann_ids = coco.getAnnIds(image_id)
|
||||
|
||||
# make person bounding boxes
|
||||
person_results = []
|
||||
for ann_id in ann_ids:
|
||||
person = {}
|
||||
ann = coco.anns[ann_id]
|
||||
# bbox format is 'xywh'
|
||||
person['bbox'] = ann['bbox']
|
||||
person_results.append(person)
|
||||
|
||||
# test a single image, with a list of bboxes
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
image_name,
|
||||
person_results,
|
||||
bbox_thr=None,
|
||||
format='xywh',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
if args.out_img_root == '':
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = os.path.join(args.out_img_root, f'vis_{i}.jpg')
|
||||
|
||||
vis_pose_result(
|
||||
pose_model,
|
||||
image_name,
|
||||
pose_results,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
show=args.show,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,138 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
process_mmdet_results, vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
from mmdet.apis import inference_detector, init_detector
|
||||
has_mmdet = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmdet = False
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('det_config', help='Config file for detection')
|
||||
parser.add_argument('det_checkpoint', help='Checkpoint file for detection')
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--img-root', type=str, default='', help='Image root')
|
||||
parser.add_argument('--img', type=str, default='', help='Image file')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show img')
|
||||
parser.add_argument(
|
||||
'--out-img-root',
|
||||
type=str,
|
||||
default='',
|
||||
help='root of the output img file. '
|
||||
'Default not saving the visualization images.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--det-cat-id',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Category id for bounding box detection model')
|
||||
parser.add_argument(
|
||||
'--bbox-thr',
|
||||
type=float,
|
||||
default=0.3,
|
||||
help='Bounding box score threshold')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_mmdet, 'Please install mmdet to run the demo.'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_img_root != '')
|
||||
assert args.img != ''
|
||||
assert args.det_config is not None
|
||||
assert args.det_checkpoint is not None
|
||||
|
||||
det_model = init_detector(
|
||||
args.det_config, args.det_checkpoint, device=args.device.lower())
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
image_name = os.path.join(args.img_root, args.img)
|
||||
|
||||
# test a single image, the resulting box is (x1, y1, x2, y2)
|
||||
mmdet_results = inference_detector(det_model, image_name)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_results = process_mmdet_results(mmdet_results, args.det_cat_id)
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
image_name,
|
||||
person_results,
|
||||
bbox_thr=args.bbox_thr,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
if args.out_img_root == '':
|
||||
out_file = None
|
||||
else:
|
||||
os.makedirs(args.out_img_root, exist_ok=True)
|
||||
out_file = os.path.join(args.out_img_root, f'vis_{args.img}')
|
||||
|
||||
# show the results
|
||||
vis_pose_result(
|
||||
pose_model,
|
||||
image_name,
|
||||
pose_results,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
show=args.show,
|
||||
out_file=out_file)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (get_track_id, inference_top_down_pose_model,
|
||||
init_pose_model, process_mmdet_results,
|
||||
vis_pose_tracking_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
from mmdet.apis import inference_detector, init_detector
|
||||
has_mmdet = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmdet = False
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('det_config', help='Config file for detection')
|
||||
parser.add_argument('det_checkpoint', help='Checkpoint file for detection')
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--det-cat-id',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Category id for bounding box detection model')
|
||||
parser.add_argument(
|
||||
'--bbox-thr',
|
||||
type=float,
|
||||
default=0.3,
|
||||
help='Bounding box score threshold')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--use-oks-tracking', action='store_true', help='Using OKS tracking')
|
||||
parser.add_argument(
|
||||
'--tracking-thr', type=float, default=0.3, help='Tracking threshold')
|
||||
parser.add_argument(
|
||||
'--euro',
|
||||
action='store_true',
|
||||
help='Using One_Euro_Filter for smoothing')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_mmdet, 'Please install mmdet to run the demo.'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
assert args.det_config is not None
|
||||
assert args.det_checkpoint is not None
|
||||
|
||||
det_model = init_detector(
|
||||
args.det_config, args.det_checkpoint, device=args.device.lower())
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
fps = None
|
||||
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
next_id = 0
|
||||
pose_results = []
|
||||
while (cap.isOpened()):
|
||||
pose_results_last = pose_results
|
||||
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
# test a single image, the resulting box is (x1, y1, x2, y2)
|
||||
mmdet_results = inference_detector(det_model, img)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_results = process_mmdet_results(mmdet_results, args.det_cat_id)
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
person_results,
|
||||
bbox_thr=args.bbox_thr,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# get track id for each person instance
|
||||
pose_results, next_id = get_track_id(
|
||||
pose_results,
|
||||
pose_results_last,
|
||||
next_id,
|
||||
use_oks=args.use_oks_tracking,
|
||||
tracking_thr=args.tracking_thr,
|
||||
use_one_euro=args.euro,
|
||||
fps=fps)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_tracking_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
vis_pose_tracking_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
from mmtrack.apis import inference_mot
|
||||
from mmtrack.apis import init_model as init_tracking_model
|
||||
has_mmtrack = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmtrack = False
|
||||
|
||||
|
||||
def process_mmtracking_results(mmtracking_results):
|
||||
"""Process mmtracking results.
|
||||
|
||||
:param mmtracking_results:
|
||||
:return: a list of tracked bounding boxes
|
||||
"""
|
||||
person_results = []
|
||||
# 'track_results' is changed to 'track_bboxes'
|
||||
# in https://github.com/open-mmlab/mmtracking/pull/300
|
||||
if 'track_bboxes' in mmtracking_results:
|
||||
tracking_results = mmtracking_results['track_bboxes'][0]
|
||||
elif 'track_results' in mmtracking_results:
|
||||
tracking_results = mmtracking_results['track_results'][0]
|
||||
|
||||
for track in tracking_results:
|
||||
person = {}
|
||||
person['track_id'] = int(track[0])
|
||||
person['bbox'] = track[1:]
|
||||
person_results.append(person)
|
||||
return person_results
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('tracking_config', help='Config file for tracking')
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--bbox-thr',
|
||||
type=float,
|
||||
default=0.3,
|
||||
help='Bounding box score threshold')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_mmtrack, 'Please install mmtrack to run the demo.'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
assert args.tracking_config is not None
|
||||
|
||||
tracking_model = init_tracking_model(
|
||||
args.tracking_config, None, device=args.device.lower())
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
frame_id = 0
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
|
||||
mmtracking_results = inference_mot(
|
||||
tracking_model, img, frame_id=frame_id)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_results = process_mmtracking_results(mmtracking_results)
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
person_results,
|
||||
bbox_thr=args.bbox_thr,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_tracking_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
frame_id += 1
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_results = [{'bbox': np.array([0, 0, size[0], size[1]])}]
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
person_results,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import os
|
||||
import warnings
|
||||
from argparse import ArgumentParser
|
||||
|
||||
import cv2
|
||||
|
||||
from mmpose.apis import (inference_top_down_pose_model, init_pose_model,
|
||||
process_mmdet_results, vis_pose_result)
|
||||
from mmpose.datasets import DatasetInfo
|
||||
|
||||
try:
|
||||
from mmdet.apis import inference_detector, init_detector
|
||||
has_mmdet = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmdet = False
|
||||
|
||||
|
||||
def main():
|
||||
"""Visualize the demo images.
|
||||
|
||||
Using mmdet to detect the human.
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('det_config', help='Config file for detection')
|
||||
parser.add_argument('det_checkpoint', help='Checkpoint file for detection')
|
||||
parser.add_argument('pose_config', help='Config file for pose')
|
||||
parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')
|
||||
parser.add_argument('--video-path', type=str, help='Video path')
|
||||
parser.add_argument(
|
||||
'--show',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='whether to show visualizations.')
|
||||
parser.add_argument(
|
||||
'--out-video-root',
|
||||
default='',
|
||||
help='Root of the output video file. '
|
||||
'Default not saving the visualization video.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--det-cat-id',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Category id for bounding box detection model')
|
||||
parser.add_argument(
|
||||
'--bbox-thr',
|
||||
type=float,
|
||||
default=0.3,
|
||||
help='Bounding box score threshold')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')
|
||||
parser.add_argument(
|
||||
'--radius',
|
||||
type=int,
|
||||
default=4,
|
||||
help='Keypoint radius for visualization')
|
||||
parser.add_argument(
|
||||
'--thickness',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Link thickness for visualization')
|
||||
|
||||
assert has_mmdet, 'Please install mmdet to run the demo.'
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
assert args.show or (args.out_video_root != '')
|
||||
assert args.det_config is not None
|
||||
assert args.det_checkpoint is not None
|
||||
|
||||
det_model = init_detector(
|
||||
args.det_config, args.det_checkpoint, device=args.device.lower())
|
||||
# build the pose model from a config file and a checkpoint file
|
||||
pose_model = init_pose_model(
|
||||
args.pose_config, args.pose_checkpoint, device=args.device.lower())
|
||||
|
||||
dataset = pose_model.cfg.data['test']['type']
|
||||
dataset_info = pose_model.cfg.data['test'].get('dataset_info', None)
|
||||
if dataset_info is None:
|
||||
warnings.warn(
|
||||
'Please set `dataset_info` in the config.'
|
||||
'Check https://github.com/open-mmlab/mmpose/pull/663 for details.',
|
||||
DeprecationWarning)
|
||||
else:
|
||||
dataset_info = DatasetInfo(dataset_info)
|
||||
|
||||
cap = cv2.VideoCapture(args.video_path)
|
||||
assert cap.isOpened(), f'Faild to load video file {args.video_path}'
|
||||
|
||||
if args.out_video_root == '':
|
||||
save_out_video = False
|
||||
else:
|
||||
os.makedirs(args.out_video_root, exist_ok=True)
|
||||
save_out_video = True
|
||||
|
||||
if save_out_video:
|
||||
fps = cap.get(cv2.CAP_PROP_FPS)
|
||||
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
|
||||
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
videoWriter = cv2.VideoWriter(
|
||||
os.path.join(args.out_video_root,
|
||||
f'vis_{os.path.basename(args.video_path)}'), fourcc,
|
||||
fps, size)
|
||||
|
||||
# optional
|
||||
return_heatmap = False
|
||||
|
||||
# e.g. use ('backbone', ) to return backbone feature
|
||||
output_layer_names = None
|
||||
|
||||
while (cap.isOpened()):
|
||||
flag, img = cap.read()
|
||||
if not flag:
|
||||
break
|
||||
# test a single image, the resulting box is (x1, y1, x2, y2)
|
||||
mmdet_results = inference_detector(det_model, img)
|
||||
|
||||
# keep the person class bounding boxes.
|
||||
person_results = process_mmdet_results(mmdet_results, args.det_cat_id)
|
||||
|
||||
# test a single image, with a list of bboxes.
|
||||
pose_results, returned_outputs = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
img,
|
||||
person_results,
|
||||
bbox_thr=args.bbox_thr,
|
||||
format='xyxy',
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
return_heatmap=return_heatmap,
|
||||
outputs=output_layer_names)
|
||||
|
||||
# show the results
|
||||
vis_img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
dataset=dataset,
|
||||
dataset_info=dataset_info,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
radius=args.radius,
|
||||
thickness=args.thickness,
|
||||
show=False)
|
||||
|
||||
if args.show:
|
||||
cv2.imshow('Image', vis_img)
|
||||
|
||||
if save_out_video:
|
||||
videoWriter.write(vis_img)
|
||||
|
||||
if args.show and cv2.waitKey(1) & 0xFF == ord('q'):
|
||||
break
|
||||
|
||||
cap.release()
|
||||
if save_out_video:
|
||||
videoWriter.release()
|
||||
if args.show:
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,585 @@
|
||||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
import argparse
|
||||
import time
|
||||
from collections import deque
|
||||
from queue import Queue
|
||||
from threading import Event, Lock, Thread
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from mmpose.apis import (get_track_id, inference_top_down_pose_model,
|
||||
init_pose_model, vis_pose_result)
|
||||
from mmpose.core import apply_bugeye_effect, apply_sunglasses_effect
|
||||
from mmpose.utils import StopWatch
|
||||
|
||||
try:
|
||||
from mmdet.apis import inference_detector, init_detector
|
||||
has_mmdet = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
has_mmdet = False
|
||||
|
||||
try:
|
||||
import psutil
|
||||
psutil_proc = psutil.Process()
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
psutil_proc = None
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--cam-id', type=str, default='0')
|
||||
parser.add_argument(
|
||||
'--det-config',
|
||||
type=str,
|
||||
default='demo/mmdetection_cfg/'
|
||||
'ssdlite_mobilenetv2_scratch_600e_coco.py',
|
||||
help='Config file for detection')
|
||||
parser.add_argument(
|
||||
'--det-checkpoint',
|
||||
type=str,
|
||||
default='https://download.openmmlab.com/mmdetection/v2.0/ssd/'
|
||||
'ssdlite_mobilenetv2_scratch_600e_coco/ssdlite_mobilenetv2_'
|
||||
'scratch_600e_coco_20210629_110627-974d9307.pth',
|
||||
help='Checkpoint file for detection')
|
||||
parser.add_argument(
|
||||
'--enable-human-pose',
|
||||
type=int,
|
||||
default=1,
|
||||
help='Enable human pose estimation')
|
||||
parser.add_argument(
|
||||
'--enable-animal-pose',
|
||||
type=int,
|
||||
default=0,
|
||||
help='Enable animal pose estimation')
|
||||
parser.add_argument(
|
||||
'--human-pose-config',
|
||||
type=str,
|
||||
default='configs/wholebody/2d_kpt_sview_rgb_img/topdown_heatmap/'
|
||||
'coco-wholebody/vipnas_res50_coco_wholebody_256x192_dark.py',
|
||||
help='Config file for human pose')
|
||||
parser.add_argument(
|
||||
'--human-pose-checkpoint',
|
||||
type=str,
|
||||
default='https://download.openmmlab.com/'
|
||||
'mmpose/top_down/vipnas/'
|
||||
'vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth',
|
||||
help='Checkpoint file for human pose')
|
||||
parser.add_argument(
|
||||
'--human-det-ids',
|
||||
type=int,
|
||||
default=[1],
|
||||
nargs='+',
|
||||
help='Object category label of human in detection results.'
|
||||
'Default is [1(person)], following COCO definition.')
|
||||
parser.add_argument(
|
||||
'--animal-pose-config',
|
||||
type=str,
|
||||
default='configs/animal/2d_kpt_sview_rgb_img/topdown_heatmap/'
|
||||
'animalpose/hrnet_w32_animalpose_256x256.py',
|
||||
help='Config file for animal pose')
|
||||
parser.add_argument(
|
||||
'--animal-pose-checkpoint',
|
||||
type=str,
|
||||
default='https://download.openmmlab.com/mmpose/animal/hrnet/'
|
||||
'hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth',
|
||||
help='Checkpoint file for animal pose')
|
||||
parser.add_argument(
|
||||
'--animal-det-ids',
|
||||
type=int,
|
||||
default=[16, 17, 18, 19, 20],
|
||||
nargs='+',
|
||||
help='Object category label of animals in detection results'
|
||||
'Default is [16(cat), 17(dog), 18(horse), 19(sheep), 20(cow)], '
|
||||
'following COCO definition.')
|
||||
parser.add_argument(
|
||||
'--device', default='cuda:0', help='Device used for inference')
|
||||
parser.add_argument(
|
||||
'--det-score-thr',
|
||||
type=float,
|
||||
default=0.5,
|
||||
help='bbox score threshold')
|
||||
parser.add_argument(
|
||||
'--kpt-thr', type=float, default=0.3, help='bbox score threshold')
|
||||
parser.add_argument(
|
||||
'--vis-mode',
|
||||
type=int,
|
||||
default=2,
|
||||
help='0-none. 1-detection only. 2-detection and pose.')
|
||||
parser.add_argument(
|
||||
'--sunglasses', action='store_true', help='Apply `sunglasses` effect.')
|
||||
parser.add_argument(
|
||||
'--bugeye', action='store_true', help='Apply `bug-eye` effect.')
|
||||
|
||||
parser.add_argument(
|
||||
'--out-video-file',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Record the video into a file. This may reduce the frame rate')
|
||||
|
||||
parser.add_argument(
|
||||
'--out-video-fps',
|
||||
type=int,
|
||||
default=20,
|
||||
help='Set the FPS of the output video file.')
|
||||
|
||||
parser.add_argument(
|
||||
'--buffer-size',
|
||||
type=int,
|
||||
default=-1,
|
||||
help='Frame buffer size. If set -1, the buffer size will be '
|
||||
'automatically inferred from the display delay time. Default: -1')
|
||||
|
||||
parser.add_argument(
|
||||
'--inference-fps',
|
||||
type=int,
|
||||
default=10,
|
||||
help='Maximum inference FPS. This is to limit the resource consuming '
|
||||
'especially when the detection and pose model are lightweight and '
|
||||
'very fast. Default: 10.')
|
||||
|
||||
parser.add_argument(
|
||||
'--display-delay',
|
||||
type=int,
|
||||
default=0,
|
||||
help='Delay the output video in milliseconds. This can be used to '
|
||||
'align the output video and inference results. The delay can be '
|
||||
'disabled by setting a non-positive delay time. Default: 0')
|
||||
|
||||
parser.add_argument(
|
||||
'--synchronous-mode',
|
||||
action='store_true',
|
||||
help='Enable synchronous mode that video I/O and inference will be '
|
||||
'temporally aligned. Note that this will reduce the display FPS.')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def process_mmdet_results(mmdet_results, class_names=None, cat_ids=1):
|
||||
"""Process mmdet results to mmpose input format.
|
||||
|
||||
Args:
|
||||
mmdet_results: raw output of mmdet model
|
||||
class_names: class names of mmdet model
|
||||
cat_ids (int or List[int]): category id list that will be preserved
|
||||
Returns:
|
||||
List[Dict]: detection results for mmpose input
|
||||
"""
|
||||
if isinstance(mmdet_results, tuple):
|
||||
mmdet_results = mmdet_results[0]
|
||||
|
||||
if not isinstance(cat_ids, (list, tuple)):
|
||||
cat_ids = [cat_ids]
|
||||
|
||||
# only keep bboxes of interested classes
|
||||
bbox_results = [mmdet_results[i - 1] for i in cat_ids]
|
||||
bboxes = np.vstack(bbox_results)
|
||||
|
||||
# get textual labels of classes
|
||||
labels = np.concatenate([
|
||||
np.full(bbox.shape[0], i - 1, dtype=np.int32)
|
||||
for i, bbox in zip(cat_ids, bbox_results)
|
||||
])
|
||||
if class_names is None:
|
||||
labels = [f'class: {i}' for i in labels]
|
||||
else:
|
||||
labels = [class_names[i] for i in labels]
|
||||
|
||||
det_results = []
|
||||
for bbox, label in zip(bboxes, labels):
|
||||
det_result = dict(bbox=bbox, label=label)
|
||||
det_results.append(det_result)
|
||||
return det_results
|
||||
|
||||
|
||||
def read_camera():
|
||||
# init video reader
|
||||
print('Thread "input" started')
|
||||
cam_id = args.cam_id
|
||||
if cam_id.isdigit():
|
||||
cam_id = int(cam_id)
|
||||
vid_cap = cv2.VideoCapture(cam_id)
|
||||
if not vid_cap.isOpened():
|
||||
print(f'Cannot open camera (ID={cam_id})')
|
||||
exit()
|
||||
|
||||
while not event_exit.is_set():
|
||||
# capture a camera frame
|
||||
ret_val, frame = vid_cap.read()
|
||||
if ret_val:
|
||||
ts_input = time.time()
|
||||
|
||||
event_inference_done.clear()
|
||||
with input_queue_mutex:
|
||||
input_queue.append((ts_input, frame))
|
||||
|
||||
if args.synchronous_mode:
|
||||
event_inference_done.wait()
|
||||
|
||||
frame_buffer.put((ts_input, frame))
|
||||
else:
|
||||
# input ending signal
|
||||
frame_buffer.put((None, None))
|
||||
break
|
||||
|
||||
vid_cap.release()
|
||||
|
||||
|
||||
def inference_detection():
|
||||
print('Thread "det" started')
|
||||
stop_watch = StopWatch(window=10)
|
||||
min_interval = 1.0 / args.inference_fps
|
||||
_ts_last = None # timestamp when last inference was done
|
||||
|
||||
while True:
|
||||
while len(input_queue) < 1:
|
||||
time.sleep(0.001)
|
||||
with input_queue_mutex:
|
||||
ts_input, frame = input_queue.popleft()
|
||||
# inference detection
|
||||
with stop_watch.timeit('Det'):
|
||||
mmdet_results = inference_detector(det_model, frame)
|
||||
|
||||
t_info = stop_watch.report_strings()
|
||||
with det_result_queue_mutex:
|
||||
det_result_queue.append((ts_input, frame, t_info, mmdet_results))
|
||||
|
||||
# limit the inference FPS
|
||||
_ts = time.time()
|
||||
if _ts_last is not None and _ts - _ts_last < min_interval:
|
||||
time.sleep(min_interval - _ts + _ts_last)
|
||||
_ts_last = time.time()
|
||||
|
||||
|
||||
def inference_pose():
|
||||
print('Thread "pose" started')
|
||||
stop_watch = StopWatch(window=10)
|
||||
|
||||
while True:
|
||||
while len(det_result_queue) < 1:
|
||||
time.sleep(0.001)
|
||||
with det_result_queue_mutex:
|
||||
ts_input, frame, t_info, mmdet_results = det_result_queue.popleft()
|
||||
|
||||
pose_results_list = []
|
||||
for model_info, pose_history in zip(pose_model_list,
|
||||
pose_history_list):
|
||||
model_name = model_info['name']
|
||||
pose_model = model_info['model']
|
||||
cat_ids = model_info['cat_ids']
|
||||
pose_results_last = pose_history['pose_results_last']
|
||||
next_id = pose_history['next_id']
|
||||
|
||||
with stop_watch.timeit(model_name):
|
||||
# process mmdet results
|
||||
det_results = process_mmdet_results(
|
||||
mmdet_results,
|
||||
class_names=det_model.CLASSES,
|
||||
cat_ids=cat_ids)
|
||||
|
||||
# inference pose model
|
||||
dataset_name = pose_model.cfg.data['test']['type']
|
||||
pose_results, _ = inference_top_down_pose_model(
|
||||
pose_model,
|
||||
frame,
|
||||
det_results,
|
||||
bbox_thr=args.det_score_thr,
|
||||
format='xyxy',
|
||||
dataset=dataset_name)
|
||||
|
||||
pose_results, next_id = get_track_id(
|
||||
pose_results,
|
||||
pose_results_last,
|
||||
next_id,
|
||||
use_oks=False,
|
||||
tracking_thr=0.3,
|
||||
use_one_euro=True,
|
||||
fps=None)
|
||||
|
||||
pose_results_list.append(pose_results)
|
||||
|
||||
# update pose history
|
||||
pose_history['pose_results_last'] = pose_results
|
||||
pose_history['next_id'] = next_id
|
||||
|
||||
t_info += stop_watch.report_strings()
|
||||
with pose_result_queue_mutex:
|
||||
pose_result_queue.append((ts_input, t_info, pose_results_list))
|
||||
|
||||
event_inference_done.set()
|
||||
|
||||
|
||||
def display():
|
||||
print('Thread "display" started')
|
||||
stop_watch = StopWatch(window=10)
|
||||
|
||||
# initialize result status
|
||||
ts_inference = None # timestamp of the latest inference result
|
||||
fps_inference = 0. # infenrece FPS
|
||||
t_delay_inference = 0. # inference result time delay
|
||||
pose_results_list = None # latest inference result
|
||||
t_info = [] # upstream time information (list[str])
|
||||
|
||||
# initialize visualization and output
|
||||
sunglasses_img = None # resource image for sunglasses effect
|
||||
text_color = (228, 183, 61) # text color to show time/system information
|
||||
vid_out = None # video writer
|
||||
|
||||
# show instructions
|
||||
print('Keyboard shortcuts: ')
|
||||
print('"v": Toggle the visualization of bounding boxes and poses.')
|
||||
print('"s": Toggle the sunglasses effect.')
|
||||
print('"b": Toggle the bug-eye effect.')
|
||||
print('"Q", "q" or Esc: Exit.')
|
||||
|
||||
while True:
|
||||
with stop_watch.timeit('_FPS_'):
|
||||
# acquire a frame from buffer
|
||||
ts_input, frame = frame_buffer.get()
|
||||
# input ending signal
|
||||
if ts_input is None:
|
||||
break
|
||||
|
||||
img = frame
|
||||
|
||||
# get pose estimation results
|
||||
if len(pose_result_queue) > 0:
|
||||
with pose_result_queue_mutex:
|
||||
_result = pose_result_queue.popleft()
|
||||
_ts_input, t_info, pose_results_list = _result
|
||||
|
||||
_ts = time.time()
|
||||
if ts_inference is not None:
|
||||
fps_inference = 1.0 / (_ts - ts_inference)
|
||||
ts_inference = _ts
|
||||
t_delay_inference = (_ts - _ts_input) * 1000
|
||||
|
||||
# visualize detection and pose results
|
||||
if pose_results_list is not None:
|
||||
for model_info, pose_results in zip(pose_model_list,
|
||||
pose_results_list):
|
||||
pose_model = model_info['model']
|
||||
bbox_color = model_info['bbox_color']
|
||||
|
||||
dataset_name = pose_model.cfg.data['test']['type']
|
||||
|
||||
# show pose results
|
||||
if args.vis_mode == 1:
|
||||
img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=4,
|
||||
thickness=2,
|
||||
dataset=dataset_name,
|
||||
kpt_score_thr=1e7,
|
||||
bbox_color=bbox_color)
|
||||
elif args.vis_mode == 2:
|
||||
img = vis_pose_result(
|
||||
pose_model,
|
||||
img,
|
||||
pose_results,
|
||||
radius=4,
|
||||
thickness=2,
|
||||
dataset=dataset_name,
|
||||
kpt_score_thr=args.kpt_thr,
|
||||
bbox_color=bbox_color)
|
||||
|
||||
# sunglasses effect
|
||||
if args.sunglasses:
|
||||
if dataset_name in {
|
||||
'TopDownCocoDataset',
|
||||
'TopDownCocoWholeBodyDataset'
|
||||
}:
|
||||
left_eye_idx = 1
|
||||
right_eye_idx = 2
|
||||
elif dataset_name == 'AnimalPoseDataset':
|
||||
left_eye_idx = 0
|
||||
right_eye_idx = 1
|
||||
else:
|
||||
raise ValueError(
|
||||
'Sunglasses effect does not support'
|
||||
f'{dataset_name}')
|
||||
if sunglasses_img is None:
|
||||
# The image attributes to:
|
||||
# https://www.vecteezy.com/free-vector/glass
|
||||
# Glass Vectors by Vecteezy
|
||||
sunglasses_img = cv2.imread(
|
||||
'demo/resources/sunglasses.jpg')
|
||||
img = apply_sunglasses_effect(img, pose_results,
|
||||
sunglasses_img,
|
||||
left_eye_idx,
|
||||
right_eye_idx)
|
||||
# bug-eye effect
|
||||
if args.bugeye:
|
||||
if dataset_name in {
|
||||
'TopDownCocoDataset',
|
||||
'TopDownCocoWholeBodyDataset'
|
||||
}:
|
||||
left_eye_idx = 1
|
||||
right_eye_idx = 2
|
||||
elif dataset_name == 'AnimalPoseDataset':
|
||||
left_eye_idx = 0
|
||||
right_eye_idx = 1
|
||||
else:
|
||||
raise ValueError('Bug-eye effect does not support'
|
||||
f'{dataset_name}')
|
||||
img = apply_bugeye_effect(img, pose_results,
|
||||
left_eye_idx, right_eye_idx)
|
||||
|
||||
# delay control
|
||||
if args.display_delay > 0:
|
||||
t_sleep = args.display_delay * 0.001 - (time.time() - ts_input)
|
||||
if t_sleep > 0:
|
||||
time.sleep(t_sleep)
|
||||
t_delay = (time.time() - ts_input) * 1000
|
||||
|
||||
# show time information
|
||||
t_info_display = stop_watch.report_strings() # display fps
|
||||
t_info_display.append(f'Inference FPS: {fps_inference:>5.1f}')
|
||||
t_info_display.append(f'Delay: {t_delay:>3.0f}')
|
||||
t_info_display.append(
|
||||
f'Inference Delay: {t_delay_inference:>3.0f}')
|
||||
t_info_str = ' | '.join(t_info_display + t_info)
|
||||
cv2.putText(img, t_info_str, (20, 20), cv2.FONT_HERSHEY_DUPLEX,
|
||||
0.3, text_color, 1)
|
||||
# collect system information
|
||||
sys_info = [
|
||||
f'RES: {img.shape[1]}x{img.shape[0]}',
|
||||
f'Buffer: {frame_buffer.qsize()}/{frame_buffer.maxsize}'
|
||||
]
|
||||
if psutil_proc is not None:
|
||||
sys_info += [
|
||||
f'CPU: {psutil_proc.cpu_percent():.1f}%',
|
||||
f'MEM: {psutil_proc.memory_percent():.1f}%'
|
||||
]
|
||||
sys_info_str = ' | '.join(sys_info)
|
||||
cv2.putText(img, sys_info_str, (20, 40), cv2.FONT_HERSHEY_DUPLEX,
|
||||
0.3, text_color, 1)
|
||||
|
||||
# save the output video frame
|
||||
if args.out_video_file is not None:
|
||||
if vid_out is None:
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
fps = args.out_video_fps
|
||||
frame_size = (img.shape[1], img.shape[0])
|
||||
vid_out = cv2.VideoWriter(args.out_video_file, fourcc, fps,
|
||||
frame_size)
|
||||
|
||||
vid_out.write(img)
|
||||
|
||||
# display
|
||||
cv2.imshow('mmpose webcam demo', img)
|
||||
keyboard_input = cv2.waitKey(1)
|
||||
if keyboard_input in (27, ord('q'), ord('Q')):
|
||||
break
|
||||
elif keyboard_input == ord('s'):
|
||||
args.sunglasses = not args.sunglasses
|
||||
elif keyboard_input == ord('b'):
|
||||
args.bugeye = not args.bugeye
|
||||
elif keyboard_input == ord('v'):
|
||||
args.vis_mode = (args.vis_mode + 1) % 3
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
if vid_out is not None:
|
||||
vid_out.release()
|
||||
event_exit.set()
|
||||
|
||||
|
||||
def main():
|
||||
global args
|
||||
global frame_buffer
|
||||
global input_queue, input_queue_mutex
|
||||
global det_result_queue, det_result_queue_mutex
|
||||
global pose_result_queue, pose_result_queue_mutex
|
||||
global det_model, pose_model_list, pose_history_list
|
||||
global event_exit, event_inference_done
|
||||
|
||||
args = parse_args()
|
||||
|
||||
assert has_mmdet, 'Please install mmdet to run the demo.'
|
||||
assert args.det_config is not None
|
||||
assert args.det_checkpoint is not None
|
||||
|
||||
# build detection model
|
||||
det_model = init_detector(
|
||||
args.det_config, args.det_checkpoint, device=args.device.lower())
|
||||
|
||||
# build pose models
|
||||
pose_model_list = []
|
||||
if args.enable_human_pose:
|
||||
pose_model = init_pose_model(
|
||||
args.human_pose_config,
|
||||
args.human_pose_checkpoint,
|
||||
device=args.device.lower())
|
||||
model_info = {
|
||||
'name': 'HumanPose',
|
||||
'model': pose_model,
|
||||
'cat_ids': args.human_det_ids,
|
||||
'bbox_color': (148, 139, 255),
|
||||
}
|
||||
pose_model_list.append(model_info)
|
||||
if args.enable_animal_pose:
|
||||
pose_model = init_pose_model(
|
||||
args.animal_pose_config,
|
||||
args.animal_pose_checkpoint,
|
||||
device=args.device.lower())
|
||||
model_info = {
|
||||
'name': 'AnimalPose',
|
||||
'model': pose_model,
|
||||
'cat_ids': args.animal_det_ids,
|
||||
'bbox_color': 'cyan',
|
||||
}
|
||||
pose_model_list.append(model_info)
|
||||
|
||||
# store pose history for pose tracking
|
||||
pose_history_list = []
|
||||
for _ in range(len(pose_model_list)):
|
||||
pose_history_list.append({'pose_results_last': [], 'next_id': 0})
|
||||
|
||||
# frame buffer
|
||||
if args.buffer_size > 0:
|
||||
buffer_size = args.buffer_size
|
||||
else:
|
||||
# infer buffer size from the display delay time
|
||||
# assume that the maximum video fps is 30
|
||||
buffer_size = round(30 * (1 + max(args.display_delay, 0) / 1000.))
|
||||
frame_buffer = Queue(maxsize=buffer_size)
|
||||
|
||||
# queue of input frames
|
||||
# element: (timestamp, frame)
|
||||
input_queue = deque(maxlen=1)
|
||||
input_queue_mutex = Lock()
|
||||
|
||||
# queue of detection results
|
||||
# element: tuple(timestamp, frame, time_info, det_results)
|
||||
det_result_queue = deque(maxlen=1)
|
||||
det_result_queue_mutex = Lock()
|
||||
|
||||
# queue of detection/pose results
|
||||
# element: (timestamp, time_info, pose_results_list)
|
||||
pose_result_queue = deque(maxlen=1)
|
||||
pose_result_queue_mutex = Lock()
|
||||
|
||||
try:
|
||||
event_exit = Event()
|
||||
event_inference_done = Event()
|
||||
t_input = Thread(target=read_camera, args=())
|
||||
t_det = Thread(target=inference_detection, args=(), daemon=True)
|
||||
t_pose = Thread(target=inference_pose, args=(), daemon=True)
|
||||
|
||||
t_input.start()
|
||||
t_det.start()
|
||||
t_pose.start()
|
||||
|
||||
# run display in the main thread
|
||||
display()
|
||||
# join the input thread (non-daemon)
|
||||
t_input.join()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user