mmpose/tests/test_codecs/test_simcc_label.py

174 lines
6.0 KiB
Python

# Copyright (c) OpenMMLab. All rights reserved.
from unittest import TestCase
import numpy as np
from mmpose.codecs import SimCCLabel # noqa: F401
from mmpose.registry import KEYPOINT_CODECS
class TestSimCCLabel(TestCase):
# name and configs of all test cases
def setUp(self) -> None:
self.configs = [
(
'simcc gaussian',
dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='gaussian',
sigma=6.0,
simcc_split_ratio=2.0),
),
(
'simcc smoothing',
dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='standard',
sigma=5.0,
simcc_split_ratio=3.0,
label_smooth_weight=0.1),
),
(
'simcc one-hot',
dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='standard',
sigma=5.0,
simcc_split_ratio=3.0),
),
(
'simcc dark',
dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='gaussian',
sigma=6.0,
simcc_split_ratio=2.0,
use_dark=True),
),
(
'simcc separated sigmas',
dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='gaussian',
sigma=(4.9, 5.66),
simcc_split_ratio=2.0),
),
]
# The bbox is usually padded so the keypoint will not be near the
# boundary
keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]
keypoints = np.round(keypoints).astype(np.float32)
keypoints_visible = np.ones((1, 17), dtype=np.float32)
self.data = dict(
keypoints=keypoints, keypoints_visible=keypoints_visible)
def test_encode(self):
keypoints = self.data['keypoints']
keypoints_visible = self.data['keypoints_visible']
for name, cfg in self.configs:
codec = KEYPOINT_CODECS.build(cfg)
encoded = codec.encode(keypoints, keypoints_visible)
self.assertEqual(encoded['keypoint_x_labels'].shape,
(1, 17, int(192 * codec.simcc_split_ratio)),
f'Failed case: "{name}"')
self.assertEqual(encoded['keypoint_y_labels'].shape,
(1, 17, int(256 * codec.simcc_split_ratio)),
f'Failed case: "{name}"')
self.assertEqual(encoded['keypoint_weights'].shape, (1, 17),
f'Failed case: "{name}"')
def test_decode(self):
for name, cfg in self.configs:
codec = KEYPOINT_CODECS.build(cfg)
simcc_x = np.random.rand(1, 17, int(192 * codec.simcc_split_ratio))
simcc_y = np.random.rand(1, 17, int(256 * codec.simcc_split_ratio))
keypoints, scores = codec.decode(simcc_x, simcc_y)
self.assertEqual(keypoints.shape, (1, 17, 2),
f'Failed case: "{name}"')
self.assertEqual(scores.shape, (1, 17), f'Failed case: "{name}"')
# test decode_visibility
cfg = cfg.copy()
cfg['decode_visibility'] = True
codec = KEYPOINT_CODECS.build(cfg)
simcc_x = np.random.rand(1, 17, int(
192 * codec.simcc_split_ratio)) * 10
simcc_y = np.random.rand(1, 17, int(
256 * codec.simcc_split_ratio)) * 10
keypoints, scores = codec.decode(simcc_x, simcc_y)
self.assertEqual(len(scores), 2)
self.assertEqual(scores[0].shape, (1, 17), f'Failed case: "{name}"')
self.assertEqual(scores[1].shape, (1, 17), f'Failed case: "{name}"')
self.assertGreaterEqual(scores[1].min(), 0.0)
self.assertLessEqual(scores[1].max(), 1.0)
def test_cicular_verification(self):
keypoints = self.data['keypoints']
keypoints_visible = self.data['keypoints_visible']
for name, cfg in self.configs:
codec = KEYPOINT_CODECS.build(cfg)
encoded = codec.encode(keypoints, keypoints_visible)
keypoint_x_labels = encoded['keypoint_x_labels']
keypoint_y_labels = encoded['keypoint_y_labels']
_keypoints, _ = codec.decode(keypoint_x_labels, keypoint_y_labels)
self.assertTrue(
np.allclose(keypoints, _keypoints, atol=5.),
f'Failed case: "{name}"')
def test_errors(self):
cfg = dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='uniform',
sigma=1.0,
simcc_split_ratio=2.0)
with self.assertRaisesRegex(ValueError,
'got invalid `smoothing_type`'):
_ = KEYPOINT_CODECS.build(cfg)
# invalid label_smooth_weight in smoothing
cfg = dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='standard',
sigma=1.0,
simcc_split_ratio=2.0,
label_smooth_weight=1.1)
with self.assertRaisesRegex(ValueError,
'`label_smooth_weight` should be'):
_ = KEYPOINT_CODECS.build(cfg)
# invalid label_smooth_weight for gaussian
cfg = dict(
type='SimCCLabel',
input_size=(192, 256),
smoothing_type='gaussian',
sigma=1.0,
simcc_split_ratio=2.0,
label_smooth_weight=0.1)
with self.assertRaisesRegex(ValueError,
'is only used for `standard` mode.'):
_ = KEYPOINT_CODECS.build(cfg)