Ultralytics YOLO27:
Get Started

Utilitários simples#

YOLO model code with 3D perspective visualization

O pacote ultralytics oferece diversos utilitários para dar suporte, aprimorar e acelerar seus fluxos de trabalho. Embora haja muitos outros disponíveis, este guia destaca alguns dos mais úteis para desenvolvedores, servindo como uma referência prática para programar com as ferramentas do Ultralytics.



Assista: Utilitários do Ultralytics | Anotação automática, Explorer API e conversão de conjuntos de dados

Dados#

Rotulagem automática / Anotações#

A anotação de conjuntos de dados é um processo que consome muitos recursos e tempo. Se você tiver um modelo Ultralytics YOLO de detecção de objetos treinado com uma quantidade razoável de dados, poderá usá-lo com o SAM para anotar automaticamente dados adicionais no formato de segmentação.

from ultralytics.data.annotator import auto_annotate

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

Esta função não retorna nenhum valor. Para mais detalhes:

Visualizar anotações de conjuntos de dados#

Esta função visualiza as anotações YOLO em uma imagem antes do treinamento, ajudando a identificar e corrigir anotações incorretas que poderiam levar a resultados de detecção errados. Ela desenha caixas delimitadoras, identifica objetos com nomes de classe e ajusta a cor do texto com base na luminância do plano de fundo para melhorar a legibilidade.

from ultralytics.data.utils import visualize_image_annotations

label_map = {  # Defina o mapa de rótulos com todos os rótulos das classes anotadas.
    0: "person",
    1: "car",
}

# Visualize
visualize_image_annotations(
    "path/to/image.jpg",  # Caminho da imagem de entrada.
    "path/to/annotations.txt",  # Caminho do arquivo de anotação da imagem.
    label_map,
)

Converter máscaras de segmentação para o formato YOLO#

Máscaras de segmentação para o formato YOLO

Use isto para converter um conjunto de dados de imagens de máscaras de segmentação para o formato de segmentação do Ultralytics YOLO. Esta função recebe o diretório que contém as imagens de máscaras no formato binário e as converte para o formato de segmentação YOLO.

As máscaras convertidas serão salvas no diretório de saída especificado.

from ultralytics.data.converter import convert_segment_masks_to_yolo_seg

# `classes` é o número total de classes no conjunto de dados.
# O conjunto de dados COCO tem 80 classes.
convert_segment_masks_to_yolo_seg(masks_dir="path/to/masks_dir", output_dir="path/to/output_dir", classes=80)

Converter COCO para o formato YOLO#

Use isto para converter anotações JSON do COCO para o formato YOLO. Para conjuntos de dados de detecção de objetos (caixas delimitadoras), defina use_segments e use_keypoints como False.

from ultralytics.data.converter import convert_coco

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

Para mais informações sobre a função convert_coco, acesse a página de referência.

Obter dimensões da caixa delimitadora#

import cv2

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

model = YOLO("yolo26n.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(f"Bounding Box Width {width.item()}, Height {height.item()}, Area {area.item()}")

Converter caixas delimitadoras em segmentos#

Com dados existentes de caixas delimitadoras x y w h, converta-os em segmentos usando a função yolo_bbox2segment. Organize os arquivos de imagens e anotações da seguinte forma:

data
|__ images
    ├─ 001.jpg
    ├─ 002.jpg
    ├─ ..
    └─ NNN.jpg
|__ labels
    ├─ 001.txt
    ├─ 002.txt
    ├─ ..
    └─ NNN.txt
from ultralytics.data.converter import yolo_bbox2segment

yolo_bbox2segment(
    im_dir="path/to/images",
    save_dir=None,  # salvo em "labels-segment" ao lado do diretório de imagens
    sam_model="sam_b.pt",
)

Acesse a página de referência de yolo_bbox2segment para obter mais informações sobre a função.

Converter segmentos em caixas delimitadoras#

Se você tiver um conjunto de dados que use o formato de conjunto de dados de segmentação, poderá convertê-los facilmente em caixas delimitadoras retas (ou horizontais) (formato x y w h) com esta função.

import numpy as np

from ultralytics.utils.ops import segments2boxes

segments = np.array(
    [
        [805, 392, 797, 400, 812, 402, 808, 714, 808, 392],
        [115, 398, 113, 400, 150, 410, 150, 400, 149, 298],
        [267, 412, 265, 413, 300, 420, 300, 413, 299, 412],
    ],
    dtype=np.float32,
)

segments2boxes([s.reshape(-1, 2) for s in segments])
# >>> array([[804.5, 553. ,  15. , 322. ],
#           [131.5, 354. ,  37. , 112. ],
#           [282.5, 416. ,  35. ,   8. ]],
# dtype=float32) # caixas delimitadoras xywh

Para entender como esta função funciona, acesse a página de referência.

Utilitários#

Compressão de imagem#

Comprima um único arquivo de imagem para reduzir seu tamanho, preservando a proporção e a qualidade. Se a imagem de entrada for menor que a dimensão máxima, ela não será redimensionada.

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)

Divisão automática de conjuntos de dados#

Divida automaticamente um conjunto de dados em partições train/val/test e salve as partições resultantes em arquivos autosplit_*.txt. Este utilitário cria arquivos de divisão persistentes; o argumento de treinamento fraction, por sua vez, seleciona um subconjunto reproduzível para uma execução.

from ultralytics.data.split import autosplit

autosplit(
    path="path/to/images",
    weights=(0.9, 0.1, 0.0),  # (partições fracionárias de treinamento, validação e teste)
    annotated_only=False,  # dividir somente imagens que tenham um arquivo de anotação quando True
)

Consulte a página de referência para mais detalhes sobre esta função.

Polígono de segmento para máscara binária#

Converta um único polígono (como uma lista) em uma máscara binária do tamanho de imagem especificado. O polígono deve ser um array 1D unidimensional de coordenadas N, com valores x, y alternados que definem o contorno do polígono.

Aviso

N deve sempre ser par.

import numpy as np

from ultralytics.data.utils import polygon2mask

imgsz = (1080, 810)
polygon = np.array([805, 392, 797, 400, ..., 808, 714, 808, 392])  # (N,) coordenadas x, y em formato plano

mask = polygon2mask(
    imgsz,  # tuple
    [polygon],  # entrada como lista
    color=255,  # binário de 8 bits
    downsample_ratio=1,
)

Caixas delimitadoras#

Instâncias de caixas delimitadoras (horizontais)#

Para gerenciar dados de caixas delimitadoras, a classe Bboxes ajuda a converter entre formatos de coordenadas de caixas, dimensionar as dimensões das caixas, calcular áreas, incluir deslocamentos e muito mais.

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

Consulte a seção de referência de Bboxes para ver mais atributos e métodos.

Dica

Muitas das funções a seguir (e outras) podem ser acessadas usando a classe Bboxes, mas, se você preferir trabalhar diretamente com as funções, consulte as próximas subseções para saber como importá-las individualmente.

Dimensionar caixas#

Ao ampliar ou reduzir uma imagem, você pode dimensionar adequadamente as coordenadas das caixas delimitadoras correspondentes para que correspondam, 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),  # dimensões da imagem original
    boxes=xyxy_boxes,  # caixas da imagem original
    img0_shape=(new_h, new_w),  # dimensões da imagem redimensionada (escalar para)
    ratio_pad=None,
    padding=False,
    xywh=False,
)

print(new_boxes)
# >>> 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]]
# )

Conversões de formato de caixas delimitadoras#

XYXY → XYWH#

Converta as coordenadas da caixa delimitadora do formato (x1, y1, x2, y2) para o formato (x, y, largura, altura), em que (x1, y1) é o canto superior esquerdo e (x2, y2) é o canto inferior direito.

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

Todas as conversões de caixas delimitadoras#

from ultralytics.utils.ops import (
    ltwh2xywh,
    ltwh2xyxy,
    xywh2ltwh,  # xywh → canto superior esquerdo, largura, altura
    xywh2xyxy,
    xywhn2xyxy,  # normalizado → pixels
    xyxy2ltwh,  # xyxy → canto superior esquerdo, largura, altura
    xyxy2xywhn,  # pixels → normalizado
)

for func in (ltwh2xywh, ltwh2xyxy, xywh2ltwh, xywh2xyxy, xywhn2xyxy, xyxy2ltwh, xyxy2xywhn):
    print(help(func))  # imprimir docstrings das funções

Consulte a docstring de cada função ou acesse a ultralytics.utils.ops página de referência para saber mais.

Plotagem#

Utilitários de anotação#

O Ultralytics inclui uma classe Annotator para anotar vários tipos de dados. Ela funciona melhor com caixas delimitadoras de detecção de objetos, pontos-chave de pose e caixas delimitadoras orientadas.

Anotação de caixas#

Exemplos de Python usando Ultralytics YOLO 🚀
import cv2 as cv
import numpy as np

from ultralytics.utils.plotting import Annotator, colors

names = {
    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()

Os nomes podem ser usados de model.names ao trabalhar com resultados de detecção. Consulte também a página de referência de Annotator para obter mais informações.

Anotação de varredura do Ultralytics#

Anotação de varredura usando os utilitários do Ultralytics
import sys

import cv2
import numpy as np

from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors

# User defined video path and model file
cap = cv2.VideoCapture("path/to/video.mp4")
model = YOLO(model="yolo26s-seg.pt")  # Model file, e.g., yolo26s.pt or yolo26m-seg.pt

if not cap.isOpened():
    print("Error: Could not open video.")
    sys.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, _, flags, param):
    """Mouse callback function to enable dragging a vertical sweep line across the video frame."""
    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.
    results = model.track(im0, persist=True)[0]

    if f == 1:
        cv2.namedWindow(window_name)
        cv2.setMouseCallback(window_name, drag_line)

    annotator = SolutionAnnotator(im0)

    if results.boxes.is_track:
        if results.masks is not None:
            masks = [np.array(m, dtype=np.int32) for m in results.masks.xy]

        boxes = results.boxes.xyxy.tolist()
        track_ids = results.boxes.id.int().cpu().tolist()
        clss = results.boxes.cls.cpu().tolist()

        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.
            label = f"{classes[cls]}:{t_id}"
            if mask is not None and mask.size > 0:
                if box[0] > line_x:
                    count += 1
                    cv2.polylines(im0, [mask], True, color, 2)
                    x, y = mask.min(axis=0)
                    (w_m, _), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
                    cv2.rectangle(im0, (x, y - 20), (x + w_m, y), color, -1)
                    cv2.putText(im0, label, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)
            else:
                if box[0] > line_x:
                    count += 1
                    annotator.box_label(box=box, color=color, label=label)

    # Generate draggable sweep line
    annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}")

    cv2.imshow(window_name, im0)
    video_writer.write(im0)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

# Release the resources
cap.release()
video_writer.release()
cv2.destroyAllWindows()

Encontre mais detalhes sobre o método sweep_annotator em nossa seção de referência aqui.

Anotação de rótulo adaptável#

SolutionAnnotator.adaptive_label desenha um rótulo cuja forma é escolhida com o argumento shape (que substitui os métodos anteriores circle_label e text_label):

  • Retângulo: annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect")
  • Círculo: annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")


Assista: Guia detalhado de anotações de texto e círculos com demonstrações ao vivo em Python | Anotações do Ultralytics 🚀
Anotação de rótulo adaptável usando os utilitários do Ultralytics
import cv2

from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors

model = YOLO("yolo26s.pt")
names = model.names
cap = cv2.VideoCapture("path/to/video.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 = SolutionAnnotator(im0)
    results = model.predict(im0)[0]
    boxes = results.boxes.xyxy.cpu()
    clss = results.boxes.cls.cpu().tolist()

    for box, cls in zip(boxes, clss):
        annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
    writer.write(im0)
    cv2.imshow("Ultralytics circle annotation", im0)

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

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

Consulta a página de referência SolutionAnnotator para obter mais informações.

Diversos#

Criação de perfil de código#

Verifica quanto tempo o código leva para ser executado/processado usando with ou como decorador.

from ultralytics.utils.ops import Profile

with Profile(device="cuda:0") as dt:
    pass  # operação a medir

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

Formatos compatíveis com Ultralytics#

Precisas de utilizar programaticamente os formatos de imagem ou vídeo suportados no Ultralytics? Usa estas constantes, se necessário:

from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS

print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}

print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}

Tornar divisível#

Calcula o menor número inteiro maior ou igual a x que seja divisível por y.

from ultralytics.utils.ops import make_divisible

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

Perguntas frequentes#

  • O pacote Ultralytics inclui utilitários concebidos para simplificar e otimizar os fluxos de trabalho de aprendizagem automática. Entre os principais utilitários estão a anotação automática para rotular conjuntos de dados, a conversão de COCO para o formato YOLO com convert_coco, a compressão de imagens e a divisão automática de conjuntos de dados. Estas ferramentas reduzem o esforço manual, garantem a consistência e aumentam a eficiência do processamento de dados.

  • Se tiveres um modelo Ultralytics YOLO pré-treinado para deteção de objetos, podes usá-lo com o modelo SAM para anotar automaticamente o teu conjunto de dados no formato de segmentação. Aqui está um exemplo:

    from ultralytics.data.annotator import auto_annotate
    
    auto_annotate(
        data="path/to/new/data",
        det_model="yolo26n.pt",
        sam_model="mobile_sam.pt",
        device="cuda",
        output_dir="path/to/save_labels",
    )

    Para mais detalhes, consulta a secção de referência de auto_annotate ou usa a Ultralytics Platform como alternativa alojada e sem código, com mascaramento baseado em cliques através de SAM 2.1, SAM 3 ou SAM 3.1, ou previsões de modelos YOLO pré-treinados e ajustados para tarefas de deteção, segmentação e OBB.

  • Para converter anotações JSON do COCO para o formato YOLO para deteção de objetos, podes usar o utilitário convert_coco. Aqui está um exemplo de código:

    from ultralytics.data.converter import convert_coco
    
    convert_coco(
        "coco/annotations/",
        use_segments=False,
        use_keypoints=False,
        cls91to80=True,
    )

    Para mais informações, visita a página de referência de convert_coco.

  • A Ultralytics Platform fornece análises automáticas do conjunto de dados: o separador Charts mostra a distribuição das divisões, as contagens das principais classes, histogramas das dimensões das imagens e mapas de calor 2D das posições das anotações, ajudando-te a identificar desequilíbrios e valores atípicos antes do treino.

  • Para converter dados existentes de caixas delimitadoras (no formato x y w h) em segmentos, podes usar a função yolo_bbox2segment. Certifica-te de que os teus ficheiros estão organizados em diretórios separados para imagens e rótulos.

    from ultralytics.data.converter import yolo_bbox2segment
    
    yolo_bbox2segment(
        im_dir="path/to/images",
        save_dir=None,  # salvo em "labels-segment" ao lado do diretório de imagens
        sam_model="sam_b.pt",
    )

    Para mais informações, visita a página de referência de yolo_bbox2segment.

Comentários