Utilitaires simples
Le ultralytics
est livré avec une myriade d'utilitaires qui peuvent prendre en charge, améliorer et accélérer vos processus de travail. Il en existe beaucoup d'autres, mais en voici quelques-uns qui seront utiles à la plupart des développeurs. Ils constituent également un excellent point de référence pour l'apprentissage de la programmation.
Regarder : Ultralytics Utilitaires | Auto Annotation, Explorer API et Conversion de jeux de données
Données
Étiquetage automatique / Annotations
L'annotation des ensembles de données est un processus très gourmand en ressources et en temps. Si vous disposez d'un modèle dedétection d'objets YOLO entraîné sur une quantité raisonnable de données, vous pouvez l'utiliser et l'utiliser pour annoter automatiquement des données supplémentaires (format de segmentation). SAM pour annoter automatiquement des données supplémentaires (format de segmentation).
from ultralytics.data.annotator import auto_annotate
auto_annotate( # (1)!
data="path/to/new/data",
det_model="yolo11n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)
-
Cette fonction ne renvoie rien
-
Voir la section de référence pour
annotator.auto_annotate
pour en savoir plus sur le fonctionnement de la fonction. -
A utiliser en combinaison avec le fonction
segments2boxes
pour générer des boîtes de délimitation pour la détection d'objets ainsi que des boîtes de délimitation pour la détection d'objets
Convertir les masques de segmentation au format YOLO
Permet de convertir un jeu de données d'images de masques de segmentation au format YOLO
format de segmentation.
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)
Conversion de COCO au format YOLO
Sert à convertir les annotations COCO JSON dans le format approprié YOLO . Pour les ensembles de données de détection d'objets (bounding box), use_segments
et use_keypoints
devraient tous deux ĂŞtre False
from ultralytics.data.converter import convert_coco
convert_coco( # (1)!
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
- Cette fonction ne renvoie rien
Pour plus d'informations sur le convert_coco
fonction, visitez la page de référence
Obtenir les dimensions du cadre de délimitation
from ultralytics.utils.plotting import Annotator
from ultralytics import YOLO
import cv2
model = YOLO('yolo11n.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("Bounding Box Width {}, Height {}, Area {}".format(
width.item(), height.item(), area.item()))
Convertir les cadres de délimitation en segments
Avec les x y w h
les données de la boîte de délimitation, les convertir en segments à l'aide de la fonction yolo_bbox2segment
fonction. Les fichiers d'images et d'annotations doivent être organisés de la manière suivante :
data
|__ images
├─ 001.jpg
├─ 002.jpg
├─ ..
└─ NNN.jpg
|__ labels
├─ 001.txt
├─ 002.txt
├─ ..
└─ NNN.txt
from ultralytics.data.converter import yolo_bbox2segment
yolo_bbox2segment( # (1)!
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)
- Cette fonction ne renvoie rien
Visitez le site yolo_bbox2segment
page de référence pour plus d'informations sur cette fonction.
Convertir les segments en boîtes englobantes
Si vous avez un jeu de données qui utilise la méthode format du jeu de données de segmentation vous pouvez facilement les convertir en boîtes de délimitation haut-droite (ou horizontale) (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 boxes
Pour comprendre le fonctionnement de cette fonction, consultez la page de référence
Utilitaires
Compression d'images
Compresse un fichier image unique à une taille réduite tout en préservant son rapport hauteur/largeur 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) # (1)!
- Cette fonction ne renvoie rien
Séparation automatique de l'ensemble de données
Diviser automatiquement un ensemble de données en train
/val
/test
et enregistrer les fractionnements résultants dans autosplit_*.txt
fichiers. Cette fonction utilise l'échantillonnage aléatoire, qui n'est pas inclus dans l'utilisation de la fonction fraction
argument en faveur de la formation.
from ultralytics.data.utils import autosplit
autosplit( # (1)!
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
)
- Cette fonction ne renvoie rien
Voir la page de référence pour plus de détails sur cette fonction.
Segmentation d'un polygone en masque binaire
Convertit un polygone unique (sous forme de liste) en un masque binaire de la taille d'image spécifiée. Polygone sous forme de [N, 2]
avec N
comme le nombre de (x, y)
points définissant le contour du polygone.
Avertissement
N
doit toujours ĂŞtre Ă©gal.
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 de délimitation
Boîte de délimitation (horizontale) Instances
Pour gérer les données relatives à la boîte de délimitation, la fonction Bboxes
permet de convertir le formatage des coordonnées des boîtes, de mettre à l'échelle les dimensions des boîtes, de calculer les surfaces, d'inclure les décalages, et bien 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]]
# )
Voir le Bboxes
section de référence pour plus d'attributs et de méthodes disponibles.
Conseil
La plupart des fonctions suivantes (et d'autres encore) sont accessibles Ă l'aide de la fonction Bboxes
classe mais si vous préférez travailler directement avec les fonctions, consultez les sous-sections suivantes pour savoir comment les importer indépendamment.
Boîtes de mise à l'échelle
Lors de la mise à l'échelle d'une image vers le haut ou vers le bas, les coordonnées de la boîte englobante correspondante peuvent être mises à l'échelle de manière appropriée à l'aide de la fonction 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) # (1)!
# >>> 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]]
# )
- Boîtes de délimitation adaptées à la nouvelle taille de l'image
Conversions de formats de boîtes englobantes
XYXY → XYWH
Convertit 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 la boîte englobante
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 docstrings
Voir la docstring pour chaque fonction ou visiter la page ultralytics.utils.ops
page de référence pour en savoir plus sur chaque fonction.
Traçage
Dessiner des annotations
Ultralytics comprend une classe Annotator qui peut être utilisée pour annoter n'importe quel type de données. Il est plus facile de l'utiliser avec les boîtes de délimitation de détection d'objet, les points clés de pose et les boîtes de délimitation orientées.
Ultralytics Annotation par balayage
Python Exemples d'utilisation de YOLO11 🚀
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors
# User defined video path and model file
cap = cv2.VideoCapture("Path/to/video/file.mp4")
model = YOLO(model="yolo11s-seg.pt") # Model file i.e. yolo11s.pt or yolo11m-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, y, flags, param): # Mouse callback for dragging line.
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.
annotator = Annotator(im0)
results = model.track(im0, persist=True) # Track objects using track method.
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
if results[0].boxes.id is not None:
if results[0].masks is not None:
masks = results[0].masks.xy
track_ids = results[0].boxes.id.int().cpu().tolist()
clss = results[0].boxes.cls.cpu().tolist()
boxes = results[0].boxes.xyxy.cpu()
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.
if mask is not None and mask.size > 0:
# If you want to overlay the masks
# mask[:, 0] = np.clip(mask[:, 0], line_x, w)
# mask_img = cv2.fillPoly(im0.copy(), [mask.astype(int)], color)
# cv2.addWeighted(mask_img, 0.5, im0, 0.5, 0, im0)
if box[0] > line_x:
count += 1
annotator.seg_bbox(mask=mask, mask_color=color, label=str(classes[cls]))
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=str(classes[cls]))
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}") # Display the sweep
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release() # Release the video capture.
video_writer.release() # Release the video writer.
cv2.destroyAllWindows() # Destroy all opened windows.
Cadres horizontaux
import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors
names = { # (1)!
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 à partir de
model.names
quand travailler avec les résultats de la détection
Boîtes de délimitation orientées (OBB)
import cv2 as cv
import numpy as np
from ultralytics.utils.plotting import Annotator, colors
obb_names = {10: "small vehicle"}
obb_image = cv.imread("datasets/dota8/images/train/P1142__1024__0___824.jpg")
obb_boxes = np.array(
[
[0, 635, 560, 919, 719, 1087, 420, 803, 261], # class-idx x1 y1 x2 y2 x3 y2 x4 y4
[0, 331, 19, 493, 260, 776, 70, 613, -171],
[9, 869, 161, 886, 147, 851, 101, 833, 115],
]
)
ann = Annotator(
obb_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
)
for obb in obb_boxes:
c_idx, *obb = obb
obb = np.array(obb).reshape(-1, 4, 2).squeeze()
label = f"{obb_names.get(int(c_idx))}"
ann.box_label(
obb,
label,
color=colors(c_idx, True),
rotated=True,
)
image_with_obb = ann.result()
Boîtes de délimitation Annotation de cercle Étiquette de cercle
Regarder : Guide détaillé des annotations de texte et de cercle avec Python Live Demos | Ultralytics Annotations 🚀
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo11s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video/file.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 = Annotator(im0)
results = model.predict(im0)
boxes = results[0].boxes.xyxy.cpu()
clss = results[0].boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.circle_label(box, label=names[int(cls)])
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()
Cadres de délimitation Annotation de texte Étiquette de texte
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo11s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video/file.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 text annotation.avi", cv2.VideoWriter_fourcc(*"MJPG"), fps, (w, h))
while True:
ret, im0 = cap.read()
if not ret:
break
annotator = Annotator(im0)
results = model.predict(im0)
boxes = results[0].boxes.xyxy.cpu()
clss = results[0].boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.text_label(box, label=names[int(cls)])
writer.write(im0)
cv2.imshow("Ultralytics text annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()
Voir le Annotator
Page de référence pour plus d'informations.
Divers
Profilage du code
Vérifier la durée d'exécution/de traitement du code à l'aide de 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"
Ultralytics Formats pris en charge
Vous souhaitez ou devez utiliser les formats d 'images ou de vidéos pris en charge par Ultralytics de manière programmatique ? Utilisez ces constantes si nécessaire.
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'tiff', 'pfm', 'bmp', 'mpo', 'dng', 'jpeg', 'png', 'webp', 'tif', 'jpg'}
print(VID_FORMATS)
# {'avi', 'mpg', 'wmv', 'mpeg', 'm4v', 'mov', 'mp4', 'asf', 'mkv', 'ts', 'gif', 'webm'}
Rendre divisible
Calcule le nombre entier le plus proche de x
pour rendre la division Ă©gale lorsqu'on la divise par y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8
FAQ
Quels sont les utilitaires inclus dans le package Ultralytics pour améliorer les flux de travail d'apprentissage automatique?
Le paquetage Ultralytics comprend une variété d'utilitaires conçus pour rationaliser et optimiser les flux de travail d'apprentissage automatique. Les principaux utilitaires comprennent l'auto-annotation pour l'étiquetage des ensembles de données, la conversion du format COCO en YOLO avec convert_coco, la compression des images et la division automatique des ensembles de données. Ces outils visent à réduire les efforts manuels, à garantir la cohérence et à améliorer l'efficacité du traitement des données.
Comment puis-je utiliser Ultralytics pour étiqueter automatiquement mon ensemble de données ?
Si vous disposez d'un modèle de détection d'objets pré-entraîné Ultralytics YOLO , vous pouvez l'utiliser avec le modèle SAM pour auto-annoter votre jeu de données au format segmentation. Voici un exemple :
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo11n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)
Pour plus de détails, consultez la section de référence auto_annotate.
Comment convertir les annotations du jeu de données COCO au format YOLO dans Ultralytics?
Pour convertir les annotations COCO JSON au format YOLO pour la détection d'objets, vous pouvez utiliser la fonction convert_coco
utilitaire. Voici un exemple de code :
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Pour plus d'informations, consultez la page de référence convert_coco.
Quel est l'objectif de l'explorateur de données YOLO dans le paquet Ultralytics ?
Le YOLO Explorateur est un outil puissant introduit dans le 8.1.0
pour améliorer la compréhension des ensembles de données. Il vous permet d'utiliser des requêtes textuelles pour trouver des instances d'objets dans votre ensemble de données, ce qui facilite l'analyse et la gestion de vos données. Cet outil fournit des informations précieuses sur la composition et la distribution des ensembles de données, ce qui permet d'améliorer la formation et les performances des modèles.
Comment convertir les boîtes de délimitation en segments dans Ultralytics?
Pour convertir des données de boîtes de délimitation existantes (dans x y w h
) Ă des segments, vous pouvez utiliser le format yolo_bbox2segment
fonction. Veillez à ce que vos fichiers soient organisés avec des répertoires distincts 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, consultez la page de référenceyolo_bbox2segment.