Utilitaires simples
Le package ultralytics propose une variété d'utilitaires pour soutenir, améliorer et accélérer tes flux de travail. Bien qu'il en existe beaucoup d'autres, ce guide met en avant certains des plus utiles pour les développeurs, servant de référence pratique pour la programmation avec les outils Ultralytics.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
Données
Étiquetage automatique / Annotations
L'annotation de jeu de données est un processus coûteux en ressources et en temps. Si tu possèdes un modèle Ultralytics YOLO de détection d'objets entraîné sur une quantité de données raisonnable, tu peux l'utiliser avec SAM pour annoter automatiquement des données supplémentaires au format de segmentation.
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",
)Cette fonction ne retourne aucune valeur. Pour plus de détails :
- Consulte la section de référence pour
annotator.auto_annotatepour mieux comprendre le fonctionnement de cette fonction. - Utilise-la en combinaison avec la fonction
segments2boxespour générer également des boîtes englobantes de détection d'objets.
Visualiser les annotations de jeu de données
Cette fonction visualise les annotations YOLO sur une image avant l'entraînement, aidant à identifier et corriger toute mauvaise annotation qui pourrait conduire à des résultats de détection incorrects. Elle dessine des boîtes englobantes, étiquette les objets avec les noms de classe et ajuste la couleur du texte en fonction de la luminance de l'arrière-plan pour une meilleure lisibilité.
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,
)Convertir des masques de segmentation au format YOLO

Utilise ceci pour convertir un jeu de données d'images de masque de segmentation au format de segmentation Ultralytics YOLO. Cette fonction prend le répertoire contenant les images de masque au format binaire et les convertit au format de segmentation YOLO.
Les masques convertis seront enregistrés dans le répertoire de sortie spécifié.
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)Convertir COCO au format YOLO
Utilise ceci pour convertir des annotations JSON COCO au format YOLO. Pour les jeux de données de détection d'objets (boîtes englobantes), définis use_segments et use_keypoints sur False.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Pour plus d'informations sur la fonction convert_coco, visite la page de référence.
Obtenir les dimensions des boîtes englobantes
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()}")Convertir des boîtes englobantes en segments
Avec des données de boîtes englobantes x y w h existantes, effectue la conversion en segments en utilisant la fonction yolo_bbox2segment. Organise les fichiers pour les images et les annotations comme suit :
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",
)Visite la page de référence de yolo_bbox2segment pour plus d'informations concernant cette fonction.
Convertir des segments en boîtes englobantes
Si tu as un jeu de données qui utilise le format de jeu de données de segmentation, tu peux facilement les convertir en boîtes englobantes verticales (ou horizontales) (format x y w h) avec cette fonction.
import numpy as np
from ultralytics.utils.ops import segments2boxes
segments = np.array(
[
[805, 392, 797, 400, ..., 808, 714, 808, 392],
[115, 398, 113, 400, ..., 150, 400, 149, 298],
[267, 412, 265, 413, ..., 300, 413, 299, 412],
]
)
segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[ 741.66, 631.12, 133.31, 479.25],
# [ 146.81, 649.69, 185.62, 502.88],
# [ 281.81, 636.19, 118.12, 448.88]],
# dtype=float32) # xywh bounding boxesPour comprendre comment fonctionne cette fonction, visite la page de référence.
Utilitaires
Compression d'image
Compresse un seul fichier image à une taille réduite tout en préservant son rapport d'aspect et sa qualité. Si l'image d'entrée est plus petite que la dimension maximale, elle ne sera pas redimensionnée.
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)Division automatique de jeu de données
Divise automatiquement un jeu de données en partitions train/val/test et enregistre les partitions résultantes dans des fichiers autosplit_*.txt. Cette fonction utilise un échantillonnage aléatoire, qui est exclu lors de l'utilisation de l'argument fraction pour l'entraînement.
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
)Consulte la page de référence pour plus de détails sur cette fonction.
Segment-polygone vers masque binaire
Convertis un seul polygone (sous forme de liste) en un masque binaire de la taille d'image spécifiée. Le polygone doit être sous la forme [N, 2], où N est le nombre de points (x, y) définissant le contour du polygone.
N doit toujours être pair.
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,
)Boîtes englobantes
Instances de boîtes englobantes (horizontales)
Pour gérer les données de boîtes englobantes, la classe Bboxes aide à convertir entre les formats de coordonnées de boîte, à mettre à l'échelle les dimensions de la boîte, à calculer les surfaces, à inclure des décalages, et plus encore.
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]]
# )Consulte la section de référence Bboxes pour plus d'attributs et de méthodes.
La plupart des fonctions suivantes (et bien d'autres) sont accessibles en utilisant la classe Bboxes, mais si tu préfères travailler directement avec les fonctions, consulte les sous-sections suivantes pour savoir comment les importer indépendamment.
Mise à l'échelle des boîtes
Lors de l'agrandissement ou de la réduction d'une image, tu peux mettre à l'échelle de manière appropriée les coordonnées des boîtes englobantes correspondantes en utilisant 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]]
# )Conversions de format de boîte englobante
XYXY → XYWH
Convertis les coordonnées de la boîte englobante du format (x1, y1, x2, y2) au format (x, y, largeur, hauteur), où (x1, y1) est le coin supérieur gauche et (x2, y2) est le coin inférieur droit.
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]]
# )Toutes les conversions de boîtes englobantes
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 docstringsSee the docstring for each function or visit the ultralytics.utils.ops reference page to read more.
Tracé
Utilitaires d'annotation
Ultralytics inclut une classe Annotator pour annoter divers types de données. Elle est mieux utilisée avec des boîtes englobantes de détection d'objets, des points clés de pose et des boîtes englobantes orientées.
Annotation de boîte
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()Les noms peuvent être utilisés depuis model.names lors du travail avec les résultats de détection. Consulte également la page de référence Annotator pour plus d'informations.
Annotation de balayage Ultralytics
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.")
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()Trouve des détails supplémentaires sur la méthode sweep_annotator dans notre section de référence ici.
Annotation d'étiquette adaptative
À partir de Ultralytics v8.3.167, circle_label et text_label ont été remplacés par une fonction unifiée adaptive_label. Tu peux désormais spécifier le type d'annotation en utilisant l'argument shape :
- Rectangle :
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect") - Cercle :
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()Consulte la page de référence SolutionAnnotator pour plus d'informations.
Divers
Profilage de code
Vérifie la durée d'exécution/traitement du code en utilisant with ou en tant que décorateur.
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"Formats supportés par Ultralytics
Besoin d'utiliser par programmation les formats d'image ou de vidéo supportés dans Ultralytics ? Utilise ces constantes si nécessaire :
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpeg2000', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}
print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}Rendre divisible
Calcule le nombre entier le plus proche de x qui est divisible par y.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8FAQ
Quels utilitaires sont inclus dans le package Ultralytics pour améliorer les flux de travail en apprentissage automatique ?
Le package Ultralytics comprend des utilitaires conçus pour rationaliser et optimiser les flux de travail d'apprentissage automatique. Les utilitaires clés incluent l'auto-annotation pour l'étiquetage des jeux de données, la conversion de COCO au format YOLO avec convert_coco, la compression d'images et la division automatique de jeux de données. Ces outils réduisent l'effort manuel, garantissent la cohérence et améliorent l'efficacité du traitement des données.
Comment puis-je utiliser Ultralytics pour étiqueter automatiquement mon jeu de données ?
Si tu disposes d'un modèle de détection d'objets Ultralytics YOLO pré-entraîné, tu peux l'utiliser avec le modèle SAM pour annoter automatiquement ton jeu de données au format de segmentation. Voici un exemple :
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",
)Pour plus de détails, consulte la section de référence auto_annotate, ou utilise Ultralytics Platform comme alternative hébergée sans code avec masquage par clic via SAM 2.1 ou SAM 3, ou des prédictions de modèles YOLO pré-entraînés et affinés pour les tâches de détection, segmentation et OBB.
Comment convertir les annotations de jeu de données COCO au format YOLO dans Ultralytics ?
Pour convertir des annotations JSON COCO au format YOLO pour la détection d'objets, tu peux utiliser l'utilitaire convert_coco. Voici un exemple d'extrait de code :
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Pour des informations supplémentaires, visite la page de référence convert_coco.
Comment puis-je analyser la composition et la distribution de mon jeu de données ?
Ultralytics Platform fournit des analyses automatiques de jeux de données : l'onglet Charts montre la distribution des partitions, le nombre de classes principales, les histogrammes des dimensions d'image et les cartes thermiques 2D des positions d'annotation, t'aidant à repérer les déséquilibres et les valeurs aberrantes avant l'entraînement.
Comment convertir des boîtes englobantes en segments dans Ultralytics ?
Pour convertir des données de boîtes englobantes existantes (au format x y w h) en segments, tu peux utiliser la fonction yolo_bbox2segment. Assure-toi que tes fichiers sont organisés avec des répertoires séparés pour les images et les étiquettes.
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",
)Pour plus d'informations, visite la page de référence yolo_bbox2segment.