Utilità semplici#
Il pacchetto ultralytics offre una serie di utilità per supportare, migliorare e accelerare i tuoi flussi di lavoro. Sebbene ce ne siano molte altre disponibili, questa guida evidenzia alcune delle più utili per gli sviluppatori, fungendo da riferimento pratico per la programmazione con gli strumenti di Ultralytics.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
Dati#
Etichettatura automatica / Annotazioni#
L'annotazione del dataset è un processo che richiede molte risorse e tempo. Se disponi di un modello di rilevamento di oggetti di Ultralytics YOLO addestrato su una quantità ragionevole di dati, puoi usarlo con SAM per auto-annotare ulteriori dati in formato di segmentazione.
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)Questa funzione non restituisce alcun valore. Per ulteriori dettagli:
- Consulta la sezione di riferimento per
annotator.auto_annotateper maggiori approfondimenti su come opera la funzione. - Usala in combinazione con la funzione
segments2boxesper generare anche i riquadri delimitatori di rilevamento degli oggetti.
Visualizzazione delle annotazioni del dataset#
Questa funzione visualizza le annotazioni YOLO su un'immagine prima dell'addestramento, aiutando a identificare e correggere eventuali annotazioni errate che potrebbero portare a risultati di rilevamento scorretti. Disegna riquadri delimitatori, etichetta gli oggetti con i nomi delle classi e regola il colore del testo in base alla luminanza dello sfondo per una migliore leggibilità.
from ultralytics.data.utils import visualize_image_annotations
label_map = { # Define the label map with all annotated class labels.
0: "person",
1: "car",
}
# Visualize
visualize_image_annotations(
"path/to/image.jpg", # Input image path.
"path/to/annotations.txt", # Annotation file path for the image.
label_map,
)Converti maschere di segmentazione in formato YOLO#

Usa questa funzione per convertire un dataset di immagini con maschere di segmentazione nel formato di segmentazione di Ultralytics YOLO. Questa funzione prende la directory contenente le immagini delle maschere in formato binario e le converte nel formato di segmentazione YOLO.
Le maschere convertite verranno salvate nella directory di output specificata.
from ultralytics.data.converter import convert_segment_masks_to_yolo_seg
# The classes here is the total classes in the dataset.
# for COCO dataset we have 80 classes.
convert_segment_masks_to_yolo_seg(masks_dir="path/to/masks_dir", output_dir="path/to/output_dir", classes=80)Converti COCO in formato YOLO#
Usa questa funzione per convertire le annotazioni JSON di COCO nel formato YOLO. Per i dataset di rilevamento di oggetti (riquadri delimitatori), imposta sia use_segments che use_keypoints su False.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Per ulteriori informazioni sulla funzione convert_coco, visita la pagina di riferimento.
Ottieni le dimensioni dei riquadri delimitatori#
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo26n.pt") # Load pretrain or fine-tune model
# Process the image
source = cv2.imread("path/to/image.jpg")
results = model(source)
# Extract results
annotator = Annotator(source, example=model.names)
for box in results[0].boxes.xyxy.cpu():
width, height, area = annotator.get_bbox_dimension(box)
print(f"Bounding Box Width {width.item()}, Height {height.item()}, Area {area.item()}")Converti riquadri delimitatori in segmenti#
Disponendo di dati di riquadri delimitatori x y w h esistenti, convertili in segmenti usando la funzione yolo_bbox2segment. Organizza i file per immagini e annotazioni come segue:
data
|__ images
├─ 001.jpg
├─ 002.jpg
├─ ..
└─ NNN.jpg
|__ labels
├─ 001.txt
├─ 002.txt
├─ ..
└─ NNN.txtfrom ultralytics.data.converter import yolo_bbox2segment
yolo_bbox2segment(
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)Visita la pagina di riferimento di yolo_bbox2segment per ulteriori informazioni sulla funzione.
Converti segmenti in riquadri delimitatori#
Se disponi di un dataset che utilizza il formato di dataset di segmentazione, puoi facilmente convertirlo in riquadri delimitatori verticali (o orizzontali) (formato x y w h) con questa funzione.
import numpy as np
from ultralytics.utils.ops import segments2boxes
segments = np.array(
[
[805, 392, 797, 400, 812, 402, 808, 714, 808, 392],
[115, 398, 113, 400, 150, 410, 150, 400, 149, 298],
[267, 412, 265, 413, 300, 420, 300, 413, 299, 412],
],
dtype=np.float32,
)
segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[804.5, 553. , 15. , 322. ],
# [131.5, 354. , 37. , 112. ],
# [282.5, 416. , 35. , 8. ]],
# dtype=float32) # xywh bounding boxesPer capire come funziona questa funzione, visita la pagina di riferimento.
Utilità#
Compressione immagini#
Comprimi un singolo file immagine a una dimensione ridotta preservandone le proporzioni e la qualità. Se l'immagine di input è più piccola della dimensione massima, non verrà ridimensionata.
from pathlib import Path
from ultralytics.data.utils import compress_one_image
for f in Path("path/to/dataset").rglob("*.jpg"):
compress_one_image(f)Divisione automatica del dataset#
Dividi automaticamente un dataset in suddivisioni train/val/test e salva le suddivisioni risultanti in file autosplit_*.txt. Questa utilità crea file di suddivisione persistenti; l'argomento di addestramento fraction seleziona invece un sottoinsieme riproducibile per un'esecuzione.
from ultralytics.data.split import autosplit
autosplit(
path="path/to/images",
weights=(0.9, 0.1, 0.0), # (train, validation, test) fractional splits
annotated_only=False, # split only images with annotation file when True
)Consulta la pagina di riferimento per ulteriori dettagli su questa funzione.
Da poligono di segmento a maschera binaria#
Converti un singolo poligono (come elenco) in una maschera binaria della dimensione dell'immagine specificata. Il poligono dovrebbe essere un array 1D piatto di coordinate N che elencano valori alternati di x, y che definiscono il contorno del poligono.
N deve essere sempre pari.
import numpy as np
from ultralytics.data.utils import polygon2mask
imgsz = (1080, 810)
polygon = np.array([805, 392, 797, 400, ..., 808, 714, 808, 392]) # (238, 2)
mask = polygon2mask(
imgsz, # tuple
[polygon], # input as list
color=255, # 8-bit binary
downsample_ratio=1,
)Riquadri delimitatori#
Istanze di riquadri delimitatori (orizzontali)#
Per gestire i dati dei riquadri delimitatori, la classe Bboxes aiuta a convertire tra formati di coordinate dei riquadri, ridimensionare le dimensioni dei riquadri, calcolare le aree, includere gli offset e altro ancora.
import numpy as np
from ultralytics.utils.instance import Bboxes
boxes = Bboxes(
bboxes=np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
),
format="xyxy",
)
boxes.areas()
# >>> array([ 4.1104e+05, 99216, 68000, 55772, 20347, 2288.5])
boxes.convert("xywh")
print(boxes.bboxes)
# >>> array(
# [[ 413.93, 494.05, 782.1, 525.56],
# [ 146.95, 650.63, 196.8, 504.15],
# [ 739.6, 634.62, 140.25, 484.85],
# [ 283.25, 631.67, 123.46, 451.74],
# [ 31.505, 711.99, 63.01, 322.91],
# [ 16.31, 289.67, 32.503, 70.41]]
# )Consulta la sezione di riferimento Bboxes per ulteriori attributi e metodi.
Molte delle seguenti funzioni (e altre) sono accessibili tramite la classe Bboxes, ma se preferisci lavorare direttamente con le funzioni, consulta le sottosezioni successive per sapere come importarle in modo indipendente.
Ridimensionamento dei riquadri#
Quando ingrandisci o riduci un'immagine, puoi ridimensionare di conseguenza le coordinate del riquadro delimitatore corrispondente utilizzando ultralytics.utils.ops.scale_boxes.
import cv2 as cv
import numpy as np
from ultralytics.utils.ops import scale_boxes
image = cv.imread("ultralytics/assets/bus.jpg")
h, w, c = image.shape
resized = cv.resize(image, None, fx=1.2, fy=1.2)
new_h, new_w, _ = resized.shape
xyxy_boxes = np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
)
new_boxes = scale_boxes(
img1_shape=(h, w), # original image dimensions
boxes=xyxy_boxes, # boxes from original image
img0_shape=(new_h, new_w), # resized image dimensions (scale to)
ratio_pad=None,
padding=False,
xywh=False,
)
print(new_boxes)
# >>> array(
# [[ 27.454, 277.52, 965.98, 908.2],
# [ 58.262, 478.27, 294.42, 1083.3],
# [ 803.36, 470.63, 971.66, 1052.4],
# [ 265.82, 486.96, 413.98, 1029],
# [ 0, 660.64, 75.612, 1048.1],
# [ 0.0701, 305.35, 39.073, 389.84]]
# )Conversioni del formato dei riquadri delimitatori#
XYXY → XYWH#
Converti le coordinate del riquadro delimitatore dal formato (x1, y1, x2, y2) al formato (x, y, larghezza, altezza), dove (x1, y1) è l'angolo superiore sinistro e (x2, y2) è l'angolo inferiore destro.
import numpy as np
from ultralytics.utils.ops import xyxy2xywh
xyxy_boxes = np.array(
[
[22.878, 231.27, 804.98, 756.83],
[48.552, 398.56, 245.35, 902.71],
[669.47, 392.19, 809.72, 877.04],
[221.52, 405.8, 344.98, 857.54],
[0, 550.53, 63.01, 873.44],
[0.0584, 254.46, 32.561, 324.87],
]
)
xywh = xyxy2xywh(xyxy_boxes)
print(xywh)
# >>> array(
# [[ 413.93, 494.05, 782.1, 525.56],
# [ 146.95, 650.63, 196.8, 504.15],
# [ 739.6, 634.62, 140.25, 484.85],
# [ 283.25, 631.67, 123.46, 451.74],
# [ 31.505, 711.99, 63.01, 322.91],
# [ 16.31, 289.67, 32.503, 70.41]]
# )Tutte le conversioni dei riquadri delimitatori#
from ultralytics.utils.ops import (
ltwh2xywh,
ltwh2xyxy,
xywh2ltwh, # xywh → top-left corner, w, h
xywh2xyxy,
xywhn2xyxy, # normalized → pixel
xyxy2ltwh, # xyxy → top-left corner, w, h
xyxy2xywhn, # pixel → normalized
)
for func in (ltwh2xywh, ltwh2xyxy, xywh2ltwh, xywh2xyxy, xywhn2xyxy, xyxy2ltwh, xyxy2xywhn):
print(help(func)) # print function docstringsConsulta la docstring per ogni funzione o visita la pagina di riferimento di ultralytics.utils.ops per saperne di più.
Visualizzazione#
Utilità di annotazione#
Ultralytics include una classe Annotator per annotare vari tipi di dati. È ideale per l'uso con riquadri delimitatori di rilevamento di oggetti, punti chiave di posa e riquadri delimitatori orientati.
Annotazione di riquadri#
import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors
names = {
0: "person",
5: "bus",
11: "stop sign",
}
image = cv.imread("ultralytics/assets/bus.jpg")
ann = Annotator(
image,
line_width=None, # default auto-size
font_size=None, # default auto-size
font="Arial.ttf", # must be ImageFont compatible
pil=False, # use PIL, otherwise uses OpenCV
)
xyxy_boxes = np.array(
[
[5, 22.878, 231.27, 804.98, 756.83], # class-idx x1 y1 x2 y2
[0, 48.552, 398.56, 245.35, 902.71],
[0, 669.47, 392.19, 809.72, 877.04],
[0, 221.52, 405.8, 344.98, 857.54],
[0, 0, 550.53, 63.01, 873.44],
[11, 0.0584, 254.46, 32.561, 324.87],
]
)
for nb, box in enumerate(xyxy_boxes):
c_idx, *box = box
label = f"{str(nb).zfill(2)}:{names.get(int(c_idx))}"
ann.box_label(box, label, color=colors(c_idx, bgr=True))
image_with_bboxes = ann.result()I nomi possono essere usati da model.names quando si lavora con i risultati di rilevamento.
Vedi anche la pagina di riferimento di Annotator per ulteriori approfondimenti.
Annotazione Sweep di Ultralytics#
import sys
import cv2
import numpy as np
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
# User defined video path and model file
cap = cv2.VideoCapture("path/to/video.mp4")
model = YOLO(model="yolo26s-seg.pt") # Model file, e.g., yolo26s.pt or yolo26m-seg.pt
if not cap.isOpened():
print("Error: Could not open video.")
sys.exit()
# Initialize the video writer object.
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
video_writer = cv2.VideoWriter("ultralytics.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
masks = None # Initialize variable to store masks data
f = 0 # Initialize frame count variable for enabling mouse event.
line_x = w # Store width of line.
dragging = False # Initialize bool variable for line dragging.
classes = model.names # Store model classes names for plotting.
window_name = "Ultralytics Sweep Annotator"
def drag_line(event, x, _, flags, param):
"""Mouse callback function to enable dragging a vertical sweep line across the video frame."""
global line_x, dragging
if event == cv2.EVENT_LBUTTONDOWN or (flags & cv2.EVENT_FLAG_LBUTTON):
line_x = max(0, min(x, w))
dragging = True
while cap.isOpened(): # Loop over the video capture object.
ret, im0 = cap.read()
if not ret:
break
f = f + 1 # Increment frame count.
count = 0 # Re-initialize count variable on every frame for precise counts.
results = model.track(im0, persist=True)[0]
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
annotator = SolutionAnnotator(im0)
if results.boxes.is_track:
if results.masks is not None:
masks = [np.array(m, dtype=np.int32) for m in results.masks.xy]
boxes = results.boxes.xyxy.tolist()
track_ids = results.boxes.id.int().cpu().tolist()
clss = results.boxes.cls.cpu().tolist()
for mask, box, cls, t_id in zip(masks or [None] * len(boxes), boxes, clss, track_ids):
color = colors(t_id, True) # Assign different color to each tracked object.
label = f"{classes[cls]}:{t_id}"
if mask is not None and mask.size > 0:
if box[0] > line_x:
count += 1
cv2.polylines(im0, [mask], True, color, 2)
x, y = mask.min(axis=0)
(w_m, _), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
cv2.rectangle(im0, (x, y - 20), (x + w_m, y), color, -1)
cv2.putText(im0, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=label)
# Generate draggable sweep line
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}")
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# Release the resources
cap.release()
video_writer.release()
cv2.destroyAllWindows()Trova ulteriori dettagli sul metodo sweep_annotator nella nostra sezione di riferimento qui.
Annotazione di etichette adattive#
SolutionAnnotator.adaptive_label disegna un'etichetta la cui forma viene scelta con l'argomento shape (sostituisce i vecchi metodi circle_label e text_label):
- Rettangolo:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect") - Cerchio:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
Watch: In-Depth Guide to Text & Circle Annotations with Python Live Demos | Ultralytics Annotations 🚀
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo26s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video.mp4")
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
writer = cv2.VideoWriter("Ultralytics circle annotation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))
while True:
ret, im0 = cap.read()
if not ret:
break
annotator = SolutionAnnotator(im0)
results = model.predict(im0)[0]
boxes = results.boxes.xyxy.cpu()
clss = results.boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()Consulta la pagina di riferimento di SolutionAnnotator per ulteriori approfondimenti.
Varie#
Profilazione del codice#
Controlla la durata di esecuzione/elaborazione del codice utilizzando with o come decoratore.
from ultralytics.utils.ops import Profile
with Profile(device="cuda:0") as dt:
pass # operation to measure
print(dt)
# >>> "Elapsed time is 9.5367431640625e-07 s"Formati supportati da Ultralytics#
Hai bisogno di usare programmaticamente i formati di immagine o video supportati in Ultralytics? Usa queste costanti se necessario:
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}
print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}Rendi divisibile#
Calcola il numero intero più piccolo maggiore o uguale a x che sia perfettamente divisibile per y.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8FAQ#
Il pacchetto Ultralytics include utilità progettate per semplificare e ottimizzare i flussi di lavoro di machine learning. Le utilità principali includono l'annotazione automatica per etichettare i dataset, la conversione da COCO a formato YOLO con convert_coco, la compressione delle immagini e la divisione automatica dei dataset. Questi strumenti riducono lo sforzo manuale, garantiscono la coerenza e migliorano l'efficienza dell'elaborazione dei dati.
Se disponi di un modello di rilevamento di oggetti Ultralytics YOLO pre-addestrato, puoi usarlo con il modello SAM per auto-annotare il tuo dataset in formato di segmentazione. Ecco un esempio:
from ultralytics.data.annotator import auto_annotate auto_annotate( data="path/to/new/data", det_model="yolo26n.pt", sam_model="mobile_sam.pt", device="cuda", output_dir="path/to/save_labels", )Per ulteriori dettagli, consulta la sezione di riferimento auto_annotate oppure usa Ultralytics Platform come alternativa ospitata senza codice con mascheramento basato su clic tramite SAM 2.1, SAM 3 o SAM 3.1, oppure previsioni da modelli YOLO preaddestrati e messi a punto per attività di rilevamento, segmentazione e OBB.
Per convertire le annotazioni JSON di COCO in formato YOLO per il rilevamento di oggetti, puoi utilizzare l'utilità
convert_coco. Ecco un frammento di codice di esempio:from ultralytics.data.converter import convert_coco convert_coco( "coco/annotations/", use_segments=False, use_keypoints=False, cls91to80=True, )Per ulteriori informazioni, visita la pagina di riferimento convert_coco.
La Piattaforma Ultralytics fornisce analisi automatiche del dataset: la scheda
Chartsmostra la distribuzione delle suddivisioni, i conteggi delle classi principali, gli istogrammi delle dimensioni delle immagini e le mappe di calore 2D delle posizioni delle annotazioni, aiutandoti a individuare sbilanciamenti e valori anomali prima dell'addestramento.Per convertire i dati dei riquadri delimitatori esistenti (nel formato
x y w h) in segmenti, puoi utilizzare la funzioneyolo_bbox2segment. Assicurati che i tuoi file siano organizzati con directory separate per immagini ed etichette.from ultralytics.data.converter import yolo_bbox2segment yolo_bbox2segment( im_dir="path/to/images", save_dir=None, # saved to "labels-segment" in the images directory sam_model="sam_b.pt", )Per maggiori informazioni, visita la pagina di riferimento yolo_bbox2segment.