Project import generated by Copybara.
GitOrigin-RevId: ff83882955f1a1e2a043ff4e71278be9d7217bbe
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
"""Tests for mediapipe.python.solutions.pose."""
|
||||
|
||||
import os
|
||||
import tempfile # pylint: disable=unused-import
|
||||
from typing import NamedTuple
|
||||
|
||||
from absl.testing import absltest
|
||||
from absl.testing import parameterized
|
||||
@@ -22,45 +24,38 @@ import numpy as np
|
||||
import numpy.testing as npt
|
||||
|
||||
# resources dependency
|
||||
# undeclared dependency
|
||||
from mediapipe.python.solutions import drawing_utils as mp_drawing
|
||||
from mediapipe.python.solutions import holistic as mp_holistic
|
||||
|
||||
TEST_IMAGE_PATH = 'mediapipe/python/solutions/testdata'
|
||||
POSE_DIFF_THRESHOLD = 30 # pixels
|
||||
HAND_DIFF_THRESHOLD = 30 # pixels
|
||||
EXPECTED_UPPER_BODY_LANDMARKS = np.array([[457, 289], [465, 278], [467, 278],
|
||||
[470, 277], [461, 279], [461, 279],
|
||||
[461, 279], [485, 277], [474, 278],
|
||||
[468, 296], [463, 297], [542, 324],
|
||||
[449, 327], [614, 321], [376, 318],
|
||||
[680, 322], [312, 310], [697, 320],
|
||||
[293, 305], [699, 314], [289, 302],
|
||||
[693, 316], [296, 305], [515, 451],
|
||||
[467, 453]])
|
||||
EXPECTED_FULL_BODY_LANDMARKS = np.array([[460, 287], [469, 277], [472, 276],
|
||||
[475, 276], [464, 277], [463, 277],
|
||||
[463, 276], [492, 277], [472, 277],
|
||||
[471, 295], [465, 295], [542, 323],
|
||||
[448, 318], [619, 319], [372, 313],
|
||||
[695, 316], [296, 308], [717, 313],
|
||||
[273, 304], [718, 304], [280, 298],
|
||||
[709, 307], [289, 303], [521, 470],
|
||||
[459, 466], [626, 533], [364, 500],
|
||||
[704, 616], [347, 614], [710, 631],
|
||||
[357, 633], [737, 625], [306, 639]])
|
||||
EXPECTED_LEFT_HAND_LANDMARKS = np.array([[698, 314], [712, 314], [721, 314],
|
||||
[727, 314], [732, 313], [728, 309],
|
||||
[738, 309], [745, 308], [751, 307],
|
||||
[724, 310], [735, 309], [742, 309],
|
||||
[747, 307], [719, 312], [727, 313],
|
||||
[729, 312], [731, 311], [713, 315],
|
||||
[717, 315], [719, 314], [719, 313]])
|
||||
EXPECTED_RIGHT_HAND_LANDMARKS = np.array([[293, 307], [284, 306], [277, 304],
|
||||
[271, 303], [266, 303], [271, 302],
|
||||
[261, 302], [254, 301], [247, 299],
|
||||
[272, 303], [261, 303], [253, 301],
|
||||
[245, 299], [275, 304], [266, 303],
|
||||
[258, 302], [252, 300], [279, 305],
|
||||
[273, 305], [268, 304], [263, 303]])
|
||||
EXPECTED_POSE_LANDMARKS = np.array([[782, 243], [791, 232], [796, 233],
|
||||
[801, 233], [773, 231], [766, 231],
|
||||
[759, 232], [802, 242], [751, 239],
|
||||
[791, 258], [766, 258], [830, 301],
|
||||
[708, 298], [910, 248], [635, 234],
|
||||
[954, 161], [593, 136], [961, 137],
|
||||
[583, 110], [952, 132], [592, 106],
|
||||
[950, 141], [596, 115], [793, 500],
|
||||
[724, 502], [874, 626], [640, 629],
|
||||
[965, 756], [542, 760], [962, 779],
|
||||
[533, 781], [1025, 797], [487, 803]])
|
||||
EXPECTED_LEFT_HAND_LANDMARKS = np.array([[958, 167], [950, 161], [945, 151],
|
||||
[945, 141], [947, 134], [945, 136],
|
||||
[939, 122], [935, 113], [931, 106],
|
||||
[951, 134], [946, 118], [942, 108],
|
||||
[938, 100], [957, 135], [954, 120],
|
||||
[951, 111], [948, 103], [964, 138],
|
||||
[964, 128], [965, 122], [965, 117]])
|
||||
EXPECTED_RIGHT_HAND_LANDMARKS = np.array([[590, 135], [602, 125], [609, 114],
|
||||
[613, 103], [617, 96], [596, 100],
|
||||
[595, 84], [594, 74], [593, 68],
|
||||
[588, 100], [586, 84], [585, 73],
|
||||
[584, 65], [581, 103], [579, 89],
|
||||
[579, 79], [579, 72], [575, 109],
|
||||
[571, 99], [570, 93], [569, 87]])
|
||||
|
||||
|
||||
class PoseTest(parameterized.TestCase):
|
||||
@@ -73,6 +68,22 @@ class PoseTest(parameterized.TestCase):
|
||||
def _assert_diff_less(self, array1, array2, threshold):
|
||||
npt.assert_array_less(np.abs(array1 - array2), threshold)
|
||||
|
||||
def _annotate(self, frame: np.ndarray, results: NamedTuple, idx: int):
|
||||
drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)
|
||||
mp_drawing.draw_landmarks(
|
||||
image=frame,
|
||||
landmark_list=results.face_landmarks,
|
||||
landmark_drawing_spec=drawing_spec)
|
||||
mp_drawing.draw_landmarks(frame, results.left_hand_landmarks,
|
||||
mp_holistic.HAND_CONNECTIONS)
|
||||
mp_drawing.draw_landmarks(frame, results.right_hand_landmarks,
|
||||
mp_holistic.HAND_CONNECTIONS)
|
||||
mp_drawing.draw_landmarks(frame, results.pose_landmarks,
|
||||
mp_holistic.POSE_CONNECTIONS)
|
||||
path = os.path.join(tempfile.gettempdir(), self.id().split('.')[-1] +
|
||||
'_frame_{}.png'.format(idx))
|
||||
cv2.imwrite(path, frame)
|
||||
|
||||
def test_invalid_image_shape(self):
|
||||
with mp_holistic.Holistic() as holistic:
|
||||
with self.assertRaisesRegex(
|
||||
@@ -86,44 +97,24 @@ class PoseTest(parameterized.TestCase):
|
||||
results = holistic.process(image)
|
||||
self.assertIsNone(results.pose_landmarks)
|
||||
|
||||
@parameterized.named_parameters(('static_image_mode', True, 3),
|
||||
('video_mode', False, 3))
|
||||
def test_upper_body_model(self, static_image_mode, num_frames):
|
||||
image_path = os.path.join(os.path.dirname(__file__), 'testdata/pose.jpg')
|
||||
with mp_holistic.Holistic(
|
||||
static_image_mode=static_image_mode, upper_body_only=True) as holistic:
|
||||
image = cv2.imread(image_path)
|
||||
for _ in range(num_frames):
|
||||
results = holistic.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
|
||||
self._assert_diff_less(
|
||||
self._landmarks_list_to_array(results.pose_landmarks, image.shape),
|
||||
EXPECTED_UPPER_BODY_LANDMARKS,
|
||||
POSE_DIFF_THRESHOLD)
|
||||
self._assert_diff_less(
|
||||
self._landmarks_list_to_array(results.left_hand_landmarks,
|
||||
image.shape),
|
||||
EXPECTED_LEFT_HAND_LANDMARKS,
|
||||
HAND_DIFF_THRESHOLD)
|
||||
self._assert_diff_less(
|
||||
self._landmarks_list_to_array(results.right_hand_landmarks,
|
||||
image.shape),
|
||||
EXPECTED_RIGHT_HAND_LANDMARKS,
|
||||
HAND_DIFF_THRESHOLD)
|
||||
# TODO: Verify the correctness of the face landmarks.
|
||||
self.assertLen(results.face_landmarks.landmark, 468)
|
||||
|
||||
@parameterized.named_parameters(('static_image_mode', True, 3),
|
||||
('video_mode', False, 3))
|
||||
def test_full_body_model(self, static_image_mode, num_frames):
|
||||
image_path = os.path.join(os.path.dirname(__file__), 'testdata/pose.jpg')
|
||||
@parameterized.named_parameters(('static_lite', True, 0, 3),
|
||||
('static_full', True, 1, 3),
|
||||
('static_heavy', True, 2, 3),
|
||||
('video_lite', False, 0, 3),
|
||||
('video_full', False, 1, 3),
|
||||
('video_heavy', False, 2, 3))
|
||||
def test_on_image(self, static_image_mode, model_complexity, num_frames):
|
||||
image_path = os.path.join(os.path.dirname(__file__),
|
||||
'testdata/holistic.jpg')
|
||||
image = cv2.imread(image_path)
|
||||
|
||||
with mp_holistic.Holistic(static_image_mode=static_image_mode) as holistic:
|
||||
for _ in range(num_frames):
|
||||
with mp_holistic.Holistic(static_image_mode=static_image_mode,
|
||||
model_complexity=model_complexity) as holistic:
|
||||
for idx in range(num_frames):
|
||||
results = holistic.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
|
||||
self._annotate(image.copy(), results, idx)
|
||||
self._assert_diff_less(
|
||||
self._landmarks_list_to_array(results.pose_landmarks, image.shape),
|
||||
EXPECTED_FULL_BODY_LANDMARKS,
|
||||
EXPECTED_POSE_LANDMARKS,
|
||||
POSE_DIFF_THRESHOLD)
|
||||
self._assert_diff_less(
|
||||
self._landmarks_list_to_array(results.left_hand_landmarks,
|
||||
|
||||
Reference in New Issue
Block a user