Vai al contenuto

Utilità semplici

codice con prospettiva

Il ultralytics è dotato di una miriade di utility che possono supportare, migliorare e velocizzare i tuoi flussi di lavoro. Ce ne sono molte altre disponibili, ma eccone alcune che saranno utili alla maggior parte degli sviluppatori. Sono anche un ottimo punto di riferimento da utilizzare quando si impara a programmare.



Guarda: Ultralytics Utilità | Annotazione automatica, API Explorer e Conversione di set di dati

Dati

YOLO Esploratore di dati

YOLO Esploratore è stato aggiunto nella sezione 8.1.0 e rappresenta un potente strumento che puoi utilizzare per comprendere meglio il tuo set di dati. Una delle funzioni chiave di YOLO Explorer è la possibilità di utilizzare query di testo per trovare istanze di oggetti nel tuo set di dati.

Etichettatura automatica / Annotazioni

L'annotazione dei dataset è un processo che richiede molte risorse e molto tempo. Se disponi di un modello di rilevamento degli oggetti YOLO addestrato su una quantità ragionevole di dati, puoi utilizzarlo e SAM per auto-annotarsi i dati aggiuntivi (formato di segmentazione).

from ultralytics.data.annotator import auto_annotate

auto_annotate(  # (1)!
    data="path/to/new/data",
    det_model="yolov8n.pt",
    sam_model="mobile_sam.pt",
    device="cuda",
    output_dir="path/to/save_labels",
)
  1. Questa funzione non restituisce nulla

  2. Vedi la sezione di riferimento per annotator.auto_annotate per maggiori informazioni sul funzionamento della funzione.

  3. Utilizzalo in combinazione con il funzione segments2boxes per generare anche i riquadri di delimitazione per il rilevamento degli oggetti

Convertire COCO in formato YOLO

Da utilizzare per convertire le annotazioni COCO JSON nel formato corretto di YOLO . Per i dataset di rilevamento di oggetti (bounding box), use_segments e use_keypoints dovrebbero essere entrambi False

from ultralytics.data.converter import convert_coco

convert_coco(  # (1)!
    "../datasets/coco/annotations/",
    use_segments=False,
    use_keypoints=False,
    cls91to80=True,
)
  1. Questa funzione non restituisce nulla

Per ulteriori informazioni su convert_coco funzione, visita la pagina di riferimento

Ottieni le dimensioni del rettangolo di selezione

from ultralytics.utils.plotting import Annotator
from ultralytics import YOLO
import cv2

model = YOLO('yolov8n.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()))

Convertire le caselle di delimitazione in segmenti

Con l'esistente x y w h i dati del riquadro di delimitazione, convertirli in segmenti utilizzando la funzione yolo_bbox2segment funzione. I file delle immagini e delle annotazioni devono essere organizzati in questo modo:

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. Questa funzione non restituisce nulla

Visita il sito yolo_bbox2segment pagina di riferimento per maggiori informazioni sulla funzione.

Convertire i segmenti in caselle di delimitazione

Se hai un set di dati che utilizza il metodo formato del set di dati di segmentazione puoi facilmente convertirli in caselle di delimitazione in alto a destra (o orizzontali) (x y w h ) con questa funzione.

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

Per capire come funziona questa funzione, visita la pagina di riferimento

Utilità

Compressione di immagini

Comprime un singolo file immagine in dimensioni ridotte preservandone il rapporto d'aspetto e la qualità. Se l'immagine in ingresso è 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)  # (1)!
  1. Questa funzione non restituisce nulla

Set di dati auto-split

Dividi automaticamente un set di dati in train/val/test e salvare le suddivisioni risultanti in autosplit_*.txt file. Questa funzione utilizzerà un campionamento casuale, che non è previsto quando si utilizza il metodo fraction argomento per la formazione.

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. Questa funzione non restituisce nulla

Per ulteriori dettagli su questa funzione, consulta la pagina di riferimento.

Da segmento-poligono a maschera binaria

Converte un singolo poligono (come elenco) in una maschera binaria della dimensione dell'immagine specificata. Poligono sotto forma di [N, 2] con N come il numero di (x, y) punti che definiscono il contorno del poligono.

Avvertenze

N deve sempre essere 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,
)

Caselle di delimitazione

Istanze Bounding Box (orizzontale)

Per gestire i dati dei riquadri di delimitazione, l'opzione Bboxes La classe ti aiuterà a convertire la formattazione delle coordinate della scatola, a scalare le dimensioni della scatola, a calcolare le aree, a includere gli offset e molto 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]]
# )

Vedi il Bboxes sezione di riferimento per ulteriori attributi e metodi disponibili.

Suggerimento

Molte delle seguenti funzioni (e altre ancora) sono accessibili utilizzando il comando Bboxes classe ma se preferisci lavorare direttamente con le funzioni, consulta le prossime sottosezioni su come importarle in modo indipendente.

Scatole in scala

Quando si scala un'immagine verso l'alto o verso il basso, le coordinate del riquadro di delimitazione corrispondenti possono essere scalate in modo appropriato per corrispondere usando 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. Caselle di delimitazione scalate per le nuove dimensioni dell'immagine

Conversioni del formato del rettangolo di selezione

XYXY → XYWH

Converte le coordinate del rettangolo di selezione dal formato (x1, y1, x2, y2) al formato (x, y, larghezza, altezza) dove (x1, y1) è l'angolo in alto a sinistra e (x2, y2) è l'angolo in basso a destra.

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 di Bounding Box

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

Consulta la docstringa di ogni funzione o visita la pagina ultralytics.utils.ops pagina di riferimento per saperne di più su ciascuna funzione.

Tracciatura

Disegno di annotazioni

Ultralytics include una classe Annotator che può essere utilizzata per annotare qualsiasi tipo di dati. È più facile utilizzarla con i rettangoli di selezione degli oggetti, i punti chiave della posa e i rettangoli di selezione orientati.

Caselle di delimitazione orizzontali

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. I nomi possono essere utilizzati da model.names quando lavorare con i risultati del rilevamento

Caselle di delimitazione orientate (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()

Caselle di delimitazione Annotazione cerchio(etichetta cerchio)

import cv2

from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors

model = YOLO("yolov8s.pt")
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, line_width=2)

    results = model.predict(im0)
    boxes = results[0].boxes.xyxy.cpu()
    clss = results[0].boxes.cls.cpu().tolist()

    for box, cls in zip(boxes, clss):
        x1, y1 = int((box[0] + box[2]) // 2), int((box[1] + box[3]) // 2)
        annotator.circle_label(box, label=model.names[int(cls)], color=colors(int(cls), True))

    writer.write(im0)
    cv2.imshow("Ultralytics circle annotation", im0)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

writer.release()
cap.release()
cv2.destroyAllWindows()

Annotazione di testo dei riquadri di delimitazione(etichetta di testo)

import cv2

from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator, colors

model = YOLO("yolov8s.pt")
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, line_width=2)

    results = model.predict(im0)
    boxes = results[0].boxes.xyxy.cpu()
    clss = results[0].boxes.cls.cpu().tolist()

    for box, cls in zip(boxes, clss):
        x1, y1 = int((box[0] + box[2]) // 2), int((box[1] + box[3]) // 2)
        annotator.text_label(box, label=model.names[int(cls)], color=colors(int(cls), True))

    writer.write(im0)
    cv2.imshow("Ultralytics text annotation", im0)

    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

writer.release()
cap.release()
cv2.destroyAllWindows()

Vedi il Annotator Pagina di riferimento per ulteriori approfondimenti.

Varie

Profilazione del codice

Controlla la durata dell'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"

Ultralytics Formati supportati

Vuoi o devi utilizzare i formati delle immagini o dei video supportati da Ultralytics in modo programmatico? Usa queste costanti se ne hai bisogno.

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'}

Rendi divisibile

Calcola il numero intero più vicino a x per essere uniformemente divisibile quando viene diviso per y.

from ultralytics.utils.ops import make_divisible

make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8

DOMANDE FREQUENTI

Quali utility sono incluse nel pacchetto Ultralytics per migliorare i flussi di lavoro di apprendimento automatico?

Il pacchetto Ultralytics include una serie di utility progettate per semplificare e ottimizzare i flussi di lavoro di apprendimento automatico. Le utility principali includono l'auto-annotazione per l'etichettatura dei set di dati, la conversione del formato COCO in YOLO con convert_coco, la compressione delle immagini e la suddivisione automatica dei set di dati. Questi strumenti mirano a ridurre il lavoro manuale, a garantire la coerenza e a migliorare l'efficienza dell'elaborazione dei dati.

Come posso utilizzare Ultralytics per etichettare automaticamente il mio set di dati?

Se disponi di un modello di rilevamento degli oggetti pre-addestrato Ultralytics YOLO , puoi utilizzarlo con il modello SAM per auto-analizzare il tuo set di dati in formato di segmentazione. Ecco un esempio:

from ultralytics.data.annotator import auto_annotate

auto_annotate(
    data="path/to/new/data",
    det_model="yolov8n.pt",
    sam_model="mobile_sam.pt",
    device="cuda",
    output_dir="path/to/save_labels",
)

Per maggiori dettagli, consulta la sezione di riferimento di auto_annotate.

Come posso convertire le annotazioni dei dataset COCO nel formato YOLO in Ultralytics?

Per convertire le annotazioni COCO JSON nel formato YOLO per il rilevamento degli oggetti, puoi utilizzare il metodo convert_coco utilità. Ecco un esempio di codice:

from ultralytics.data.converter import convert_coco

convert_coco(
    "../datasets/coco/annotations/",
    use_segments=False,
    use_keypoints=False,
    cls91to80=True,
)

Per ulteriori informazioni, visita la pagina di riferimento di convert_coco.

Qual è lo scopo di YOLO Data Explorer nel pacchetto Ultralytics ?

Il YOLO Esploratore è un potente strumento introdotto nella 8.1.0 per migliorare la comprensione del dataset. Ti permette di utilizzare query di testo per trovare istanze di oggetti nel tuo set di dati, rendendo più facile l'analisi e la gestione dei tuoi dati. Questo strumento fornisce preziose informazioni sulla composizione e sulla distribuzione del set di dati, aiutando a migliorare la formazione e le prestazioni dei modelli.

Come posso convertire i rettangoli di selezione in segmenti in Ultralytics?

Per convertire i dati dei rettangoli di selezione esistenti (in x y w h ) ai segmenti, puoi utilizzare il metodo yolo_bbox2segment funzione. Assicurati che i tuoi file siano organizzati con directory separate per le immagini e le 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 riferimentoyolo_bbox2segment.



Creato 2024-02-20, Aggiornato 2024-07-04
Autori: glenn-jocher (9), ambitious-octopus (1), IvorZhu331 (1), RizwanMunawar (1), Burhan-Q (2)

Commenti