Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/keypoints from mediapipe #1232

Merged
merged 11 commits into from
Jun 13, 2024
52 changes: 52 additions & 0 deletions supervision/keypoint/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import math
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
from contextlib import suppress
from dataclasses import dataclass, field
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
Expand Down Expand Up @@ -185,6 +186,57 @@ class IDs, and confidences of each keypoint.
data=data,
)

@classmethod
def from_mediapipe(
cls, mediapipe_results, resolution: Tuple[int, int]
) -> KeyPoints:
"""
Creates a KeyPoints instance from a
[Pose landmark detection](https://ai.google.dev/edge/mediapipe/)
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
inference result.

Args:
mediapipe_results (mediapipe.python.solution_base.SolutionOutputs):
The output Results from Mediapipe
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
resolution (Tuple[int, int]): image resolution (w, h) since mediapipe
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
only provides normalized coordinates

Returns:
KeyPoints: A new KeyPoints object.

Example:
```python
import cv2
import mediapipe as mp
import supervision as sv

mp_pose = mp.solutions.pose
image = cv2.imread(<SOURCE_IMAGE_PATH>)
pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.5)
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
keypoints = sv.KeyPoints.from_mediapipe(results)
```
"""
if mediapipe_results.pose_landmarks is None:
return cls.empty()

prediction_xy = []
prediction_confidence = []

for landmark in mediapipe_results.pose_landmarks.landmark:
prediction_xy.append(
[
min(math.floor(landmark.x * resolution[0]), resolution[0] - 1),
min(math.floor(landmark.y * resolution[1]), resolution[1] - 1),
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
]
)
prediction_confidence.append(landmark.visibility)

return cls(
xy=np.array([prediction_xy], dtype=np.float32),
LinasKo marked this conversation as resolved.
Show resolved Hide resolved
confidence=np.array([prediction_confidence], dtype=np.float32),
)

@classmethod
def from_ultralytics(cls, ultralytics_results) -> KeyPoints:
"""
Expand Down
38 changes: 38 additions & 0 deletions supervision/keypoint/skeletons.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,44 @@ class Skeleton(Enum):
(17, 15),
]

GHUM = [
(1, 2),
(1, 5),
(2, 3),
(3, 4),
(4, 8),
(5, 6),
(6, 7),
(7, 9),
(10, 11),
(12, 13),
(12, 14),
(12, 24),
(13, 15),
(13, 25),
(14, 16),
(15, 17),
(16, 18),
(15, 19),
(16, 22),
(17, 19),
(17, 21),
(17, 23),
(18, 20),
(19, 21),
(24, 25),
(24, 26),
(25, 27),
(26, 28),
(27, 29),
(28, 30),
(28, 32),
(29, 31),
(29, 33),
(30, 32),
(31, 33),
]


SKELETONS_BY_EDGE_COUNT: Dict[int, Edges] = {}
SKELETONS_BY_VERTEX_COUNT: Dict[int, Edges] = {}
Expand Down
Loading