0
# Keypoint Annotators
1
2
Specialized annotators for drawing keypoints, skeletal connections, and pose estimation results. These annotators work with KeyPoints data structures to visualize human poses, facial landmarks, and other keypoint-based detections.
3
4
## Capabilities
5
6
### Vertex Annotation
7
8
Draw individual keypoints as circles on the image.
9
10
```python { .api }
11
class VertexAnnotator(BaseKeyPointAnnotator):
12
"""
13
A class that specializes in drawing skeleton vertices on images using specified keypoints.
14
15
Args:
16
color (Color): The color to use for annotating keypoints
17
radius (int): The radius of the circles used to represent keypoints
18
"""
19
def __init__(
20
self,
21
color: Color = Color.ROBOFLOW,
22
radius: int = 4
23
) -> None: ...
24
25
def annotate(self, scene: ImageType, key_points: KeyPoints) -> ImageType:
26
"""
27
Annotates the given scene with skeleton vertices based on the provided keypoints.
28
29
Args:
30
scene: The image where skeleton vertices will be drawn
31
key_points: A collection of keypoints with x,y coordinates
32
33
Returns:
34
The annotated image matching the input type
35
36
Example:
37
```python
38
import supervision as sv
39
40
image = ...
41
key_points = sv.KeyPoints(...)
42
43
vertex_annotator = sv.VertexAnnotator(
44
color=sv.Color.GREEN,
45
radius=10
46
)
47
annotated_frame = vertex_annotator.annotate(
48
scene=image.copy(),
49
key_points=key_points
50
)
51
```
52
"""
53
```
54
55
### Edge Annotation
56
57
Draw lines connecting keypoints to form skeletal structures.
58
59
```python { .api }
60
class EdgeAnnotator(BaseKeyPointAnnotator):
61
"""
62
A class that specializes in drawing skeleton edges on images using specified keypoints.
63
It connects keypoints with lines to form the skeleton structure.
64
65
Args:
66
color (Color): The color to use for the edges
67
thickness (int): The thickness of the edges
68
edges (list[tuple[int, int]] | None): The edges to draw. If None, will attempt to select automatically
69
"""
70
def __init__(
71
self,
72
color: Color = Color.ROBOFLOW,
73
thickness: int = 2,
74
edges: list[tuple[int, int]] | None = None
75
) -> None: ...
76
77
def annotate(self, scene: ImageType, key_points: KeyPoints) -> ImageType:
78
"""
79
Annotates the given scene by drawing lines between specified keypoints to form edges.
80
81
Args:
82
scene: The image where skeleton edges will be drawn
83
key_points: A collection of keypoints with x,y coordinates
84
85
Returns:
86
The annotated image matching the input type
87
88
Example:
89
```python
90
import supervision as sv
91
92
image = ...
93
key_points = sv.KeyPoints(...)
94
95
edge_annotator = sv.EdgeAnnotator(
96
color=sv.Color.GREEN,
97
thickness=5
98
)
99
annotated_frame = edge_annotator.annotate(
100
scene=image.copy(),
101
key_points=key_points
102
)
103
```
104
"""
105
```
106
107
### Vertex Label Annotation
108
109
Add text labels to keypoints showing vertex indices or names.
110
111
```python { .api }
112
class VertexLabelAnnotator:
113
"""
114
A class that draws labels of skeleton vertices on images using specified keypoints.
115
116
Args:
117
color (Color): The color to use for the text labels
118
text_color (Color): The color of the text
119
text_scale (float): The scale factor for text size
120
text_thickness (int): The thickness of the text
121
text_padding (int): Padding around the text
122
border_radius (int): Radius for rounded text background
123
"""
124
def __init__(
125
self,
126
color: Color = Color.ROBOFLOW,
127
text_color: Color = Color.WHITE,
128
text_scale: float = 0.5,
129
text_thickness: int = 1,
130
text_padding: int = 10,
131
border_radius: int = 0
132
) -> None: ...
133
134
def annotate(
135
self,
136
scene: ImageType,
137
key_points: KeyPoints,
138
labels: list[str] | None = None
139
) -> ImageType:
140
"""
141
Annotates the given scene with labels at keypoint locations.
142
143
Args:
144
scene: The image where vertex labels will be drawn
145
key_points: A collection of keypoints with x,y coordinates
146
labels: Optional list of custom labels. If None, uses vertex indices
147
148
Returns:
149
The annotated image matching the input type
150
"""
151
```
152
153
### Base Class
154
155
Abstract base class for all keypoint annotators.
156
157
```python { .api }
158
class BaseKeyPointAnnotator(ABC):
159
"""Abstract base class for keypoint annotators."""
160
161
@abstractmethod
162
def annotate(self, scene: ImageType, key_points: KeyPoints) -> ImageType:
163
"""Abstract method for annotating keypoints on an image."""
164
```
165
166
## Usage Examples
167
168
### Basic Pose Visualization
169
170
```python
171
import supervision as sv
172
import cv2
173
from ultralytics import YOLO
174
175
# Load pose estimation model
176
model = YOLO("yolov8n-pose.pt")
177
image = cv2.imread("person.jpg")
178
179
# Get pose keypoints
180
results = model(image)[0]
181
keypoints = sv.KeyPoints.from_ultralytics(results)
182
183
# Create annotators
184
vertex_annotator = sv.VertexAnnotator(
185
color=sv.Color.RED,
186
radius=6
187
)
188
edge_annotator = sv.EdgeAnnotator(
189
color=sv.Color.BLUE,
190
thickness=3
191
)
192
193
# Annotate the image
194
annotated_image = vertex_annotator.annotate(image.copy(), keypoints)
195
annotated_image = edge_annotator.annotate(annotated_image, keypoints)
196
197
cv2.imshow("Pose Estimation", annotated_image)
198
cv2.waitKey(0)
199
```
200
201
### Custom Skeleton with Labels
202
203
```python
204
import supervision as sv
205
206
# Define custom skeleton connections
207
custom_edges = [
208
(1, 2), (2, 3), (3, 4), # Head to shoulders
209
(2, 5), (5, 6), (6, 7), # Left arm
210
(2, 8), (8, 9), (9, 10), # Right arm
211
(2, 11), (11, 12), # Torso
212
(11, 13), (13, 14), (14, 15), # Left leg
213
(11, 16), (16, 17), (17, 18) # Right leg
214
]
215
216
# Create annotators with custom configuration
217
edge_annotator = sv.EdgeAnnotator(
218
color=sv.Color.GREEN,
219
thickness=2,
220
edges=custom_edges
221
)
222
223
vertex_annotator = sv.VertexAnnotator(
224
color=sv.Color.YELLOW,
225
radius=5
226
)
227
228
label_annotator = sv.VertexLabelAnnotator(
229
color=sv.Color.BLACK,
230
text_color=sv.Color.WHITE,
231
text_scale=0.4,
232
text_padding=5,
233
border_radius=3
234
)
235
236
# Keypoint names for labeling
237
keypoint_names = [
238
"nose", "left_eye", "right_eye", "left_ear", "right_ear",
239
"left_shoulder", "right_shoulder", "left_elbow", "right_elbow",
240
"left_wrist", "right_wrist", "left_hip", "right_hip",
241
"left_knee", "right_knee", "left_ankle", "right_ankle"
242
]
243
244
# Apply all annotations
245
annotated_image = edge_annotator.annotate(image.copy(), keypoints)
246
annotated_image = vertex_annotator.annotate(annotated_image, keypoints)
247
annotated_image = label_annotator.annotate(
248
annotated_image, keypoints, labels=keypoint_names
249
)
250
```
251
252
### Multi-Person Pose Visualization
253
254
```python
255
import supervision as sv
256
257
# Process multiple people in the image
258
for i, person_keypoints in enumerate(all_keypoints):
259
# Use different colors for each person
260
colors = [sv.Color.RED, sv.Color.BLUE, sv.Color.GREEN, sv.Color.YELLOW]
261
person_color = colors[i % len(colors)]
262
263
# Create person-specific annotators
264
vertex_annotator = sv.VertexAnnotator(
265
color=person_color,
266
radius=4
267
)
268
edge_annotator = sv.EdgeAnnotator(
269
color=person_color,
270
thickness=2
271
)
272
273
# Annotate each person
274
image = vertex_annotator.annotate(image, person_keypoints)
275
image = edge_annotator.annotate(image, person_keypoints)
276
277
# Display the result
278
cv2.imshow("Multi-Person Poses", image)
279
```
280
281
### Automatic Skeleton Detection
282
283
The EdgeAnnotator automatically detects appropriate skeleton structures based on the number of keypoints:
284
285
```python
286
import supervision as sv
287
288
# EdgeAnnotator will automatically select skeleton based on keypoint count
289
edge_annotator = sv.EdgeAnnotator(
290
color=sv.Color.BLUE,
291
thickness=2
292
# edges=None (automatic selection)
293
)
294
295
# Works with different pose models:
296
# - 17 keypoints: COCO pose format
297
# - 21 keypoints: MediaPipe hand landmarks
298
# - 68 keypoints: Facial landmark detection
299
# - Custom formats: Define your own edges
300
301
annotated_image = edge_annotator.annotate(image, keypoints)
302
```