Overslaan naar inhoud

Eenvoudige hulpprogramma's

code met perspectief

De ultralytics pakket wordt geleverd met een groot aantal hulpprogramma's die je werkprocessen kunnen ondersteunen, verbeteren en versnellen. Er zijn er nog veel meer beschikbaar, maar hier zijn er een paar die nuttig zijn voor de meeste ontwikkelaars. Ze zijn ook een goed referentiepunt om te gebruiken als je leert programmeren.



Kijken: Ultralytics Hulpprogramma's | Auto Annotatie, Verkenner API en Dataset Conversie

Gegevens

YOLO Gegevensverkenner

YOLO Verkenner werd toegevoegd in de 8.1.0 verjaardag update en is een krachtig hulpmiddel dat je kunt gebruiken om je dataset beter te begrijpen. Een van de belangrijkste functies die YOLO Explorer biedt, is de mogelijkheid om tekstqueries te gebruiken om objectinstanties in je dataset te vinden.

Automatisch labelen / Annotaties

Dataset annotatie is een zeer arbeidsintensief en tijdrovend proces. Als je een YOLO objectdetectiemodel hebt dat is getraind op een redelijke hoeveelheid gegevens, dan kun je dit gebruiken en SAM om aanvullende gegevens automatisch te annoteren (segmentatieformaat).

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. Er komt niets terug van deze functie

  2. Zie het referentiegedeelte voor annotator.auto_annotate voor meer inzicht in hoe de functie werkt.

  3. Gebruik in combinatie met de functie segments2boxes om ook objectdetectie bounding boxes te genereren

COCO omzetten in YOLO formaat

Te gebruiken om COCO JSON annotaties te converteren naar het juiste YOLO formaat. Voor objectdetectie (bounding box) datasets, use_segments en use_keypoints moeten beide False

from ultralytics.data.converter import convert_coco

convert_coco(  # (1)!
    "../datasets/coco/annotations/",
    use_segments=False,
    use_keypoints=False,
    cls91to80=True,
)
  1. Er komt niets terug van deze functie

Voor meer informatie over de convert_coco functie, bezoek de referentiepagina

Verkrijg de afmetingen van het begrenzingskader

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()))

Begrenzende vakken omzetten naar segmenten

Met bestaande x y w h begrenzende boxgegevens, converteren naar segmenten met de yolo_bbox2segment functie. De bestanden voor afbeeldingen en annotaties moeten als volgt worden georganiseerd:

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. Er komt niets terug van deze functie

Bezoek de yolo_bbox2segment referentiepagina voor meer informatie over de functie.

Segmenten converteren naar begrenzende kaders

Als je een dataset hebt die de segmentatie dataset formaat kun je deze eenvoudig omzetten in rechtopstaande (of horizontale) bounding boxes (x y w h formaat) met deze functie.

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

Ga naar de referentiepagina om te begrijpen hoe deze functie werkt

Nutsbedrijven

Beeldcompressie

Comprimeert een enkel afbeeldingsbestand tot een kleiner formaat met behoud van de beeldverhouding en kwaliteit. Als de ingevoerde afbeelding kleiner is dan de maximale afmeting, wordt het formaat niet aangepast.

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. Er komt niets terug van deze functie

Dataset automatisch splitsen

Een dataset automatisch opsplitsen in train/val/test splitsingen en sla de resulterende splitsingen op in autosplit_*.txt bestanden. Deze functie maakt gebruik van willekeurige steekproeven, die niet worden uitgevoerd bij gebruik van fraction argument voor training.

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. Er komt niets terug van deze functie

Zie de pagina Verwijzingen voor meer informatie over deze functie.

Segment-polygoon naar binair masker

Converteer een enkele veelhoek (als lijst) naar een binair masker van de opgegeven afbeeldingsgrootte. Veelhoek in de vorm van [N, 2] met N als het aantal (x, y) punten die de veelhoekcontour definiëren.

Waarschuwing

N moeten altijd gelijk zijn.

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,
)

Begrenzende vakken

Bounding Box (horizontaal) instanties

Om bounding box gegevens te beheren, moet de Bboxes De klasse helpt bij het converteren tussen boxcoördinaatformaten, het schalen van boxafmetingen, het berekenen van oppervlakten, het opnemen van offsets en nog veel meer!

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]]
# )

Zie de Bboxes referentiesectie voor meer beschikbare attributen en methoden.

Tip

Veel van de volgende functies (en meer) zijn toegankelijk met de Bboxes klasse maar als je liever direct met de functies werkt, kijk dan in de volgende paragrafen hoe je deze onafhankelijk kunt importeren.

Schaaldozen

Bij het omhoog of omlaag schalen van een afbeelding kunnen de bijbehorende begrenzende boxcoördinaten passend worden geschaald met behulp van 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. Afbakeningsvelden geschaald voor de nieuwe afbeeldingsgrootte

Conversies van begrenzende boxformaten

XYXY → XYWH

Converteer bounding box coördinaten van (x1, y1, x2, y2) formaat naar (x, y, breedte, hoogte) formaat waarbij (x1, y1) de linkerbovenhoek is en (x2, y2) de rechterbenedenhoek.

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]]
# )

Alle begrenzingen omrekenen

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

Zie de docstring voor elke functie of bezoek de ultralytics.utils.ops referentiepagina om meer te lezen over elke functie.

Plotten

Annotaties tekenen

Ultralytics bevat een Annotator klasse die kan worden gebruikt om elk soort gegevens te annoteren. Het is het gemakkelijkst om te gebruiken met objectdetectie bounding boxes, pose key points en georiënteerde bounding boxes.

Horizontale begrenzingen

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. Namen kunnen worden gebruikt van model.names wanneer werken met detectieresultaten

Georiënteerde begrenzende vakken (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()

Begrenzingskaders Cirkel Annotatie(Cirkel Label)

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()

Kader Tekst Annotatie(Tekstlabel)

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()

Zie de Annotator Referentiebladzijde voor meer inzicht.

Diverse

Code profilering

Controleer de duur van het uitvoeren/verwerken van code met behulp van with of als decorateur.

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 Ondersteunde formaten

Wil of moet je de formaten van afbeeldingen of videotypes die worden ondersteund door Ultralytics programmatisch gebruiken? Gebruik dan deze constanten.

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

Deelbaar maken

Berekent het dichtstbijzijnde gehele getal tot x om gelijk deelbaar te maken bij deling door y.

from ultralytics.utils.ops import make_divisible

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

FAQ

Welke hulpprogramma's zijn opgenomen in het Ultralytics pakket om machine learning workflows te verbeteren?

Het pakket Ultralytics bevat een aantal hulpprogramma's die zijn ontworpen om werkstromen voor machinaal leren te stroomlijnen en te optimaliseren. De belangrijkste hulpprogramma's zijn auto-annotatie voor het labelen van datasets, het converteren van COCO naar YOLO formaat met convert_coco, het comprimeren van afbeeldingen en het automatisch splitsen van datasets. Deze hulpprogramma's zijn bedoeld om handmatige inspanningen te verminderen, consistentie te garanderen en de efficiëntie van gegevensverwerking te verbeteren.

Hoe kan ik Ultralytics gebruiken om mijn dataset automatisch te labelen?

Als je een voorgetraind Ultralytics YOLO objectdetectiemodel hebt, kun je dit gebruiken met het SAM model gebruiken om je dataset automatisch te segmenteren. Hier is een voorbeeld:

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",
)

Kijk voor meer details in de auto_annotate referentiesectie.

Hoe converteer ik COCO annotaties van datasets naar YOLO formaat in Ultralytics?

Om COCO JSON annotaties te converteren naar YOLO formaat voor objectdetectie, kun je de optie convert_coco hulpprogramma. Hier is een voorbeeld van een codefragment:

from ultralytics.data.converter import convert_coco

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

Ga voor meer informatie naar de referentiepagina van convert_coco.

Wat is het doel van de YOLO Data Explorer in het pakket Ultralytics ?

De YOLO Verkenner is een krachtig hulpmiddel dat is geïntroduceerd in de 8.1.0 update om het begrip van de dataset te verbeteren. Je kunt tekstquery's gebruiken om objectinstanties in je dataset te vinden, waardoor het eenvoudiger wordt om je gegevens te analyseren en te beheren. Dit hulpmiddel geeft waardevolle inzichten in de samenstelling en verdeling van de dataset, waardoor de modeltraining en -prestaties worden verbeterd.

Hoe kan ik bounding boxes converteren naar segmenten in Ultralytics?

Om bestaande begrenzingskadergegevens te converteren (in x y w h formaat) naar segmenten, kun je de yolo_bbox2segment functie. Zorg ervoor dat je bestanden georganiseerd zijn met aparte mappen voor afbeeldingen en labels.

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",
)

Ga voor meer informatie naar yolo_bbox2segment referentiepagina.



Aangemaakt 2024-02-20, Bijgewerkt 2024-07-04
Auteurs: glenn-jocher (9), ambitious-octopus (1), IvorZhu331 (1), RizwanMunawar (1), Burhan-Q (2)

Reacties