Skip to content

Utilitaires simples

code avec perspective

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",
)
  1. Cette fonction ne renvoie rien

  2. Voir la section de référence pour annotator.auto_annotate pour en savoir plus sur le fonctionnement de la fonction.

  3. 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

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,
)
  1. 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",
)
  1. 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)!
  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
)
  1. 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]]
# )
  1. 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()
  1. 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.

📅 Created 9 months ago ✏️ Updated 15 days ago

Commentaires