Zum Inhalt springen

Einfache Dienstprogramme

Code mit Perspektive

Die ultralytics Paket wird mit einer Vielzahl von Dienstprogrammen geliefert, die deine ArbeitsablĂ€ufe unterstĂŒtzen, verbessern und beschleunigen können. Es gibt noch viele weitere, aber hier sind einige, die fĂŒr die meisten Entwickler/innen nĂŒtzlich sind. Sie sind auch ein guter Bezugspunkt, wenn du programmieren lernst.

Daten

YOLO Daten-Explorer

YOLO Entdecker wurde in der 8.1.0 und ist ein leistungsstarkes Werkzeug, mit dem du deinen Datensatz besser verstehen kannst. Eine der wichtigsten Funktionen von YOLO Explorer ist die Möglichkeit, mit Textabfragen Objektinstanzen in deinem Datensatz zu finden.

Automatische Beschriftung / Anmerkungen

Die Annotation von DatensÀtzen ist ein sehr ressourcenintensiver und zeitaufwÀndiger Prozess. Wenn du ein YOLO Objekterkennungsmodell hast, das auf einer angemessenen Menge von Daten trainiert wurde, kannst du es verwenden und SAM um zusÀtzliche Daten automatisch zu annotieren (Segmentierungsformat).

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. Von dieser Funktion kommt nichts zurĂŒck

  2. Siehe den Referenzabschnitt fĂŒr annotator.auto_annotate um mehr darĂŒber zu erfahren, wie die Funktion funktioniert.

  3. Verwendung in Kombination mit dem Funktion segments2boxes um auch Boundingboxen fĂŒr die Objekterkennung zu erstellen

COCO ins YOLO Format konvertieren

Konvertiert COCO JSON-Annotationen in das richtige YOLO Format. FĂŒr DatensĂ€tze zur Objekterkennung (Bounding Box), use_segments und use_keypoints sollten beide False

from ultralytics.data.converter import convert_coco

convert_coco(#(1)!
    '../datasets/coco/annotations/',
    use_segments=False, 
    use_keypoints=False,
    cls91to80=True,
)
  1. Von dieser Funktion kommt nichts zurĂŒck

FĂŒr zusĂ€tzliche Informationen ĂŒber die convert_coco Funktion, besuche die Referenzseite

Bounding Box Abmessungen erhalten

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

Bounding Boxes in Segmente umwandeln

Mit bestehenden x y w h Bounding-Box-Daten, konvertiere sie in Segmente, indem du die yolo_bbox2segment Funktion. Die Dateien fĂŒr Bilder und Anmerkungen mĂŒssen wie folgt organisiert werden:

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. Von dieser Funktion kommt nichts zurĂŒck

Besuchen Sie die yolo_bbox2segment Referenzseite fĂŒr weitere Informationen zu dieser Funktion.

Segmente in Bounding Boxes umwandeln

Wenn du einen Datensatz hast, der die Format des Segmentierungsdatensatzes kannst du diese ganz einfach in Up-Right (oder horizontale) Bounding Boxes umwandeln (x y w h Format) mit dieser Funktion.

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

Um zu verstehen, wie diese Funktion funktioniert, besuche die Referenzseite

Versorgungsunternehmen

Bildkomprimierung

Komprimiert eine einzelne Bilddatei auf eine geringere GrĂ¶ĂŸe, wobei das SeitenverhĂ€ltnis und die QualitĂ€t des Bildes erhalten bleiben. Wenn das Eingangsbild kleiner als die maximale GrĂ¶ĂŸe ist, wird es nicht verkleinert.

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. Von dieser Funktion kommt nichts zurĂŒck

Automatisch geteilter Datensatz

Automatisches Aufteilen eines Datensatzes in train/val/test Splits und speichern die resultierenden Splits in autosplit_*.txt Dateien. Diese Funktion verwendet eine Zufallsstichprobe, die nicht enthalten ist, wenn du fraction Argument fĂŒr die Ausbildung.

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. Von dieser Funktion kommt nichts zurĂŒck

Weitere Informationen zu dieser Funktion findest du auf der Seite Referenz.

Segment-Polygon zu BinÀrmaske

Konvertiert ein einzelnes Polygon (als Liste) in eine binĂ€re Maske mit der angegebenen BildgrĂ¶ĂŸe. Polygon in Form von [N, 2] mit N als die Anzahl der (x, y) Punkte, die die Polygonkontur definieren.

Warnung

N muss immer gerade sein.

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
) 

Bounding Boxes

Bounding Box (horizontal) Instanzen

Um Bounding-Box-Daten zu verwalten, muss die Bboxes Klasse hilft dir dabei, zwischen verschiedenen Koordinatenformaten zu konvertieren, die Abmessungen von Boxen zu skalieren, FlĂ€chen zu berechnen, Offsets zu berĂŒcksichtigen und vieles mehr!

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

Siehe die Bboxes Referenzabschnitt fĂŒr weitere verfĂŒgbare Attribute und Methoden.

Tipp

Auf viele der folgenden Funktionen (und mehr) kann mit der Bboxes Klasse Wenn du aber lieber direkt mit den Funktionen arbeiten möchtest, erfÀhrst du in den nÀchsten Unterabschnitten, wie du sie unabhÀngig voneinander importieren kannst.

Skalierungsboxen

Wenn ein Bild nach oben oder unten skaliert wird, können die entsprechenden Bounding-Box-Koordinaten mithilfe von 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,
)

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. Bounding Boxes skaliert fĂŒr die neue BildgrĂ¶ĂŸe

Bounding Box Format Konvertierungen

XYXY → XYWH

Konvertiert Bounding-Box-Koordinaten vom Format (x1, y1, x2, y2) in das Format (x, y, Breite, Höhe), wobei (x1, y1) die obere linke Ecke und (x2, y2) die untere rechte Ecke ist.

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)

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

from ultralytics.utils.ops import xywh2xyxy
from ultralytics.utils.ops import xywhn2xyxy # normalized → pixel
from ultralytics.utils.ops import xyxy2xywhn # pixel → normalized
from ultralytics.utils.ops import xywh2ltwh  # xywh → top-left corner, w, h
from ultralytics.utils.ops import xyxy2ltwh  # xyxy → top-left corner, w, h
from ultralytics.utils.ops import ltwh2xywh
from ultralytics.utils.ops import ltwh2xyxy

Siehe Docstring fĂŒr jede Funktion oder besuche die ultralytics.utils.ops Referenzseite um mehr ĂŒber jede Funktion zu erfahren.

Plotten

Anmerkungen zeichnen

Ultralytics enthĂ€lt eine Annotator-Klasse, mit der du jede Art von Daten annotieren kannst. Am einfachsten ist es, sie fĂŒr Bounding Boxes zur Objekterkennung, Pose Key Points und orientierte Bounding Boxes zu verwenden.

Horizontale Bounding Boxes

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 können verwendet werden von model.names wenn Arbeit mit Aufdeckungsergebnissen

Oriented Bounding Boxes (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"{names.get(int(c_idx))}"
    ann.box_label(
        obb,
        label,
        color=colors(c_idx, True),
        rotated=True,
    )

image_with_obb = ann.result()

Siehe die Annotator Referenzseite fĂŒr zusĂ€tzliche Einblicke.

Sonstiges

Code Profiling

ÜberprĂŒfe die Dauer fĂŒr die AusfĂŒhrung/Bearbeitung des Codes entweder mit with oder als Dekorateur.

from ultralytics.utils.ops import Profile

with Profile(device=device) as dt:
    pass  # operation to measure

print(dt)
>>> "Elapsed time is 9.5367431640625e-07 s"

Ultralytics UnterstĂŒtzte Formate

Willst oder musst du die von Ultralytics unterstĂŒtzten Bild- oder Videoformate programmatisch verwenden? Verwende diese Konstanten, wenn du sie brauchst.

from ultralytics.data.utils import IMG_FORMATS
from ultralytics.data.utils import VID_FORMATS

print(IMG_FORMATS)
>>> ('bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm')

Teilbar machen

Berechnet die nĂ€chstliegende ganze Zahl zu x gleichmĂ€ĂŸig teilbar zu machen, wenn es durch y.

from ultralytics.utils.ops import make_divisible

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


Erstellt 2024-02-20, Aktualisiert 2024-04-05
Autoren: RizwanMunawar (1), Burhan-Q (2), glenn-jocher (1)

Kommentare