0
# Results and Visualization
1
2
Rich result objects containing detection outputs with built-in visualization, annotation, and export capabilities for comprehensive analysis and presentation of model predictions.
3
4
## Capabilities
5
6
### Results Object
7
8
The Results class encapsulates all prediction outputs and provides methods for visualization and data export.
9
10
```python { .api }
11
class Results:
12
def __init__(self, orig_img, path, names, boxes=None, masks=None, probs=None, keypoints=None, obb=None):
13
"""
14
Initialize Results object.
15
16
Parameters:
17
- orig_img (np.ndarray): Original input image
18
- path (str): Image file path
19
- names (dict): Class names dictionary
20
- boxes (Boxes, optional): Detection boxes
21
- masks (Masks, optional): Segmentation masks
22
- probs (Probs, optional): Classification probabilities
23
- keypoints (Keypoints, optional): Pose keypoints
24
- obb (OBB, optional): Oriented bounding boxes
25
"""
26
27
# Core properties
28
orig_img: np.ndarray # Original input image
29
orig_shape: tuple # Original image shape (height, width)
30
boxes: Optional[Boxes] # Detection boxes
31
masks: Optional[Masks] # Segmentation masks
32
probs: Optional[Probs] # Classification probabilities
33
keypoints: Optional[Keypoints] # Pose estimation keypoints
34
obb: Optional[OBB] # Oriented bounding boxes
35
speed: dict # Inference speed metrics
36
names: dict # Class names dictionary
37
path: str # Source image path
38
39
def plot(self, conf=True, line_width=None, font_size=None, font='Arial.ttf',
40
pil=False, img=None, im_gpu=None, kpt_radius=5, kpt_line=True,
41
labels=True, boxes=True, masks=True, probs=True, **kwargs) -> np.ndarray:
42
"""
43
Plot prediction results on image.
44
45
Parameters:
46
- conf (bool): Plot confidence scores (default: True)
47
- line_width (int): Line thickness (default: auto)
48
- font_size (int): Font size (default: auto)
49
- font (str): Font file path (default: 'Arial.ttf')
50
- pil (bool): Return PIL Image instead of numpy array (default: False)
51
- img (np.ndarray): Custom image to plot on (default: self.orig_img)
52
- im_gpu (torch.Tensor): GPU image tensor for faster plotting
53
- kpt_radius (int): Keypoint radius (default: 5)
54
- kpt_line (bool): Draw keypoint connections (default: True)
55
- labels (bool): Plot class labels (default: True)
56
- boxes (bool): Plot bounding boxes (default: True)
57
- masks (bool): Plot segmentation masks (default: True)
58
- probs (bool): Plot classification probabilities (default: True)
59
60
Returns:
61
np.ndarray: Annotated image as numpy array
62
"""
63
64
def show(self, *args, **kwargs):
65
"""Display the annotated image."""
66
67
def save(self, filename=None, *args, **kwargs):
68
"""Save the annotated image to file."""
69
70
def verbose(self) -> str:
71
"""Return verbose string representation of results."""
72
73
def save_txt(self, txt_file, save_conf=False):
74
"""Save results to txt file in YOLO format."""
75
76
def save_crop(self, save_dir, file_name=None):
77
"""Save cropped detections to directory."""
78
79
def tojson(self, normalize=False):
80
"""Convert results to JSON format."""
81
82
def pandas(self):
83
"""Convert results to pandas DataFrame."""
84
```
85
86
**Usage Examples:**
87
88
```python
89
from ultralytics import YOLO
90
import cv2
91
92
# Load model and make predictions
93
model = YOLO("yolo11n.pt")
94
results = model("image.jpg")
95
96
# Access result properties
97
result = results[0]
98
print(f"Image shape: {result.orig_shape}")
99
print(f"Number of detections: {len(result.boxes)}")
100
print(f"Speed: {result.speed}")
101
102
# Plot results with custom styling
103
annotated_img = result.plot(
104
conf=True,
105
line_width=2,
106
font_size=12,
107
labels=True,
108
boxes=True
109
)
110
111
# Display result
112
result.show()
113
114
# Save annotated result
115
result.save("annotated_image.jpg")
116
117
# Save crops of detected objects
118
result.save_crop("crops/")
119
120
# Export to different formats
121
result.save_txt("detections.txt", save_conf=True)
122
json_data = result.tojson(normalize=True)
123
df = result.pandas()
124
```
125
126
### Detection Boxes
127
128
Container for object detection bounding boxes with associated metadata.
129
130
```python { .api }
131
class Boxes:
132
def __init__(self, boxes, orig_shape):
133
"""
134
Initialize Boxes object.
135
136
Parameters:
137
- boxes (torch.Tensor): Detection boxes tensor [N, 6] (x1, y1, x2, y2, conf, cls)
138
- orig_shape (tuple): Original image shape
139
"""
140
141
# Core properties
142
xyxy: torch.Tensor # Bounding boxes in xyxy format [N, 4]
143
conf: torch.Tensor # Confidence scores [N]
144
cls: torch.Tensor # Class predictions [N]
145
id: Optional[torch.Tensor] # Track IDs [N] (for tracking)
146
xywh: torch.Tensor # Boxes in xywh format [N, 4]
147
xyxyn: torch.Tensor # Normalized xyxy boxes [N, 4]
148
xywhn: torch.Tensor # Normalized xywh boxes [N, 4]
149
150
def __len__(self) -> int:
151
"""Return number of boxes."""
152
153
def __getitem__(self, idx) -> 'Boxes':
154
"""Get subset of boxes by index."""
155
156
@property
157
def cpu(self) -> 'Boxes':
158
"""Return boxes on CPU."""
159
160
@property
161
def numpy(self) -> 'Boxes':
162
"""Return boxes as numpy arrays."""
163
```
164
165
**Usage Examples:**
166
167
```python
168
# Access detection boxes
169
if result.boxes is not None:
170
boxes = result.boxes
171
172
# Get box coordinates
173
xyxy = boxes.xyxy.cpu().numpy() # [[x1, y1, x2, y2], ...]
174
xywh = boxes.xywh.cpu().numpy() # [[x, y, w, h], ...]
175
176
# Get confidence scores and classes
177
confidences = boxes.conf.cpu().numpy()
178
classes = boxes.cls.cpu().numpy()
179
180
# Iterate through detections
181
for i, (box, conf, cls) in enumerate(zip(xyxy, confidences, classes)):
182
x1, y1, x2, y2 = box
183
print(f"Detection {i}: class={cls}, conf={conf:.2f}, box=[{x1:.1f}, {y1:.1f}, {x2:.1f}, {y2:.1f}]")
184
185
# Filter high-confidence detections
186
high_conf_mask = boxes.conf > 0.5
187
high_conf_boxes = boxes[high_conf_mask]
188
189
# Get tracking IDs (if available)
190
if boxes.id is not None:
191
track_ids = boxes.id.cpu().numpy()
192
print(f"Track IDs: {track_ids}")
193
```
194
195
### Segmentation Masks
196
197
Container for instance segmentation masks with polygon and bitmap representations.
198
199
```python { .api }
200
class Masks:
201
def __init__(self, masks, orig_shape):
202
"""
203
Initialize Masks object.
204
205
Parameters:
206
- masks (torch.Tensor): Segmentation masks tensor
207
- orig_shape (tuple): Original image shape
208
"""
209
210
# Core properties
211
data: torch.Tensor # Raw mask data
212
xy: List[np.ndarray] # Mask polygons in xy format
213
xyn: List[np.ndarray] # Normalized mask polygons
214
215
def __len__(self) -> int:
216
"""Return number of masks."""
217
218
def __getitem__(self, idx) -> 'Masks':
219
"""Get subset of masks by index."""
220
221
@property
222
def cpu(self) -> 'Masks':
223
"""Return masks on CPU."""
224
225
@property
226
def numpy(self) -> 'Masks':
227
"""Return masks as numpy arrays."""
228
```
229
230
**Usage Examples:**
231
232
```python
233
# Access segmentation masks
234
if result.masks is not None:
235
masks = result.masks
236
237
# Get mask data
238
mask_data = masks.data.cpu().numpy() # [N, H, W]
239
240
# Get polygon representations
241
polygons = masks.xy # List of [n_points, 2] arrays
242
normalized_polygons = masks.xyn # Normalized coordinates
243
244
# Process each mask
245
for i, (mask, polygon) in enumerate(zip(mask_data, polygons)):
246
print(f"Mask {i}: {mask.shape}, polygon points: {len(polygon)}")
247
248
# Convert mask to binary image
249
binary_mask = (mask > 0.5).astype(np.uint8) * 255
250
251
# Save individual mask
252
cv2.imwrite(f"mask_{i}.png", binary_mask)
253
254
# Use polygon for further processing
255
# polygon is shape [n_points, 2] with (x, y) coordinates
256
```
257
258
### Classification Probabilities
259
260
Container for image classification results with class probabilities.
261
262
```python { .api }
263
class Probs:
264
def __init__(self, probs, orig_shape=None):
265
"""
266
Initialize Probs object.
267
268
Parameters:
269
- probs (torch.Tensor): Classification probabilities
270
- orig_shape (tuple): Original image shape
271
"""
272
273
# Core properties
274
data: torch.Tensor # Raw probability data [num_classes]
275
top1: int # Index of top-1 class
276
top5: List[int] # Indices of top-5 classes
277
top1conf: float # Confidence of top-1 class
278
top5conf: List[float] # Confidences of top-5 classes
279
280
@property
281
def cpu(self) -> 'Probs':
282
"""Return probabilities on CPU."""
283
284
@property
285
def numpy(self) -> 'Probs':
286
"""Return probabilities as numpy arrays."""
287
```
288
289
**Usage Examples:**
290
291
```python
292
# Access classification probabilities
293
if result.probs is not None:
294
probs = result.probs
295
296
# Get top predictions
297
top1_class = probs.top1
298
top1_conf = probs.top1conf
299
top5_classes = probs.top5
300
top5_confs = probs.top5conf
301
302
print(f"Top-1: class {top1_class} ({top1_conf:.3f})")
303
print("Top-5:")
304
for cls, conf in zip(top5_classes, top5_confs):
305
class_name = result.names[cls]
306
print(f" {class_name}: {conf:.3f}")
307
308
# Get all probabilities
309
all_probs = probs.data.cpu().numpy()
310
for i, prob in enumerate(all_probs):
311
if prob > 0.01: # Only show significant probabilities
312
print(f"{result.names[i]}: {prob:.3f}")
313
```
314
315
### Pose Keypoints
316
317
Container for pose estimation keypoints with skeletal connections.
318
319
```python { .api }
320
class Keypoints:
321
def __init__(self, keypoints, orig_shape):
322
"""
323
Initialize Keypoints object.
324
325
Parameters:
326
- keypoints (torch.Tensor): Keypoint coordinates and visibility
327
- orig_shape (tuple): Original image shape
328
"""
329
330
# Core properties
331
data: torch.Tensor # Raw keypoint data [N, num_keypoints, 3] (x, y, visibility)
332
xy: torch.Tensor # Keypoint coordinates [N, num_keypoints, 2]
333
xyn: torch.Tensor # Normalized keypoint coordinates
334
conf: torch.Tensor # Keypoint confidence/visibility scores
335
336
def __len__(self) -> int:
337
"""Return number of pose instances."""
338
339
def __getitem__(self, idx) -> 'Keypoints':
340
"""Get subset of keypoints by index."""
341
342
@property
343
def cpu(self) -> 'Keypoints':
344
"""Return keypoints on CPU."""
345
346
@property
347
def numpy(self) -> 'Keypoints':
348
"""Return keypoints as numpy arrays."""
349
```
350
351
**Usage Examples:**
352
353
```python
354
# Access pose keypoints
355
if result.keypoints is not None:
356
keypoints = result.keypoints
357
358
# Get keypoint data
359
kpts_data = keypoints.data.cpu().numpy() # [N, num_keypoints, 3]
360
kpts_xy = keypoints.xy.cpu().numpy() # [N, num_keypoints, 2]
361
kpts_conf = keypoints.conf.cpu().numpy() # [N, num_keypoints]
362
363
# Process each person
364
for person_idx, (kpts, confs) in enumerate(zip(kpts_xy, kpts_conf)):
365
print(f"Person {person_idx}:")
366
367
# Standard COCO keypoint names
368
keypoint_names = [
369
'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear',
370
'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow',
371
'left_wrist', 'right_wrist', 'left_hip', 'right_hip',
372
'left_knee', 'right_knee', 'left_ankle', 'right_ankle'
373
]
374
375
for kpt_idx, ((x, y), conf) in enumerate(zip(kpts, confs)):
376
if conf > 0.5: # Only show visible keypoints
377
kpt_name = keypoint_names[kpt_idx] if kpt_idx < len(keypoint_names) else f"kpt_{kpt_idx}"
378
print(f" {kpt_name}: ({x:.1f}, {y:.1f}) conf={conf:.2f}")
379
```
380
381
### Visualization Customization
382
383
Advanced visualization options for different use cases and presentation needs.
384
385
```python { .api }
386
# Custom color palettes
387
def generate_colors(n, colormap='hsv'):
388
"""Generate n distinct colors."""
389
390
def plot_masks(img, masks, colors, alpha=0.3):
391
"""Plot segmentation masks with transparency."""
392
393
def plot_keypoints(img, keypoints, skeleton=None, kpt_color=None, limb_color=None):
394
"""Plot pose keypoints with skeletal connections."""
395
396
def draw_text(img, text, pos, font_scale=0.4, color=(255, 255, 255), thickness=1):
397
"""Draw text on image with background rectangle."""
398
```
399
400
**Usage Examples:**
401
402
```python
403
# Custom visualization
404
annotated = result.plot(
405
conf=True, # Show confidence scores
406
line_width=3, # Thick bounding boxes
407
font_size=16, # Large font
408
labels=True, # Show class labels
409
boxes=True, # Show bounding boxes
410
masks=True, # Show segmentation masks
411
kpt_radius=8, # Large keypoint circles
412
kpt_line=True # Show pose connections
413
)
414
415
# Save high-quality result
416
result.save("high_quality_result.png")
417
418
# Custom color scheme for specific classes
419
colors = {0: (255, 0, 0), 1: (0, 255, 0), 2: (0, 0, 255)} # Red, Green, Blue
420
custom_annotated = result.plot(colors=colors)
421
```
422
423
## Types
424
425
```python { .api }
426
from typing import List, Optional, Dict, Tuple, Any, Union
427
import torch
428
import numpy as np
429
from PIL import Image
430
431
# Core result types
432
ResultsList = List[Results]
433
434
# Bounding box formats
435
BboxXYXY = torch.Tensor # [N, 4] - (x1, y1, x2, y2)
436
BboxXYWH = torch.Tensor # [N, 4] - (x_center, y_center, width, height)
437
BboxNormalized = torch.Tensor # [N, 4] - normalized coordinates [0, 1]
438
439
# Mask types
440
MaskBitmap = torch.Tensor # [N, H, W] - binary masks
441
MaskPolygon = List[np.ndarray] # List of polygon coordinates
442
443
# Keypoint types
444
KeypointData = torch.Tensor # [N, num_keypoints, 3] - (x, y, visibility)
445
KeypointXY = torch.Tensor # [N, num_keypoints, 2] - (x, y) coordinates
446
447
# Classification types
448
ClassProbs = torch.Tensor # [num_classes] - class probabilities
449
ClassIndices = List[int] # List of class indices
450
451
# Visualization types
452
ColorTuple = Tuple[int, int, int] # RGB color (0-255)
453
ColorDict = Dict[int, ColorTuple] # Class ID to color mapping
454
ImageArray = np.ndarray # HWC image array
455
PILImage = Image.Image # PIL Image object
456
457
# Export types
458
JSONDict = Dict[str, Any] # JSON export format
459
DataFrameType = 'pandas.DataFrame' # Pandas DataFrame type
460
```