Utilitários Simples
O ultralytics
package fornece uma variedade de utilitários para suportar, aprimorar e acelerar seus fluxos de trabalho. Embora haja muitos mais disponíveis, este guia destaca alguns dos mais úteis para desenvolvedores, servindo como uma referência prática para programar com as ferramentas Ultralytics.
Assista: Utilitários Ultralytics | Auto Anotação, API Explorer e Conversão de Dataset
Dados
Rotulagem / Anotações Automáticas
A anotação de conjuntos de dados é um processo moroso e que exige muitos recursos. Se tiver um modelo Ultralytics YOLO de deteção de objetos treinado numa quantidade razoável de dados, pode utilizá-lo com o SAM para autoanotar dados adicionais em formato de segmentação.
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",
)
Esta função não retorna nenhum valor. Para mais detalhes:
- Veja o arquivo seção de referência para
annotator.auto_annotate
para obter mais informações sobre como a função opera. - Use em combinação com a função função
segments2boxes
para gerar também bounding boxes de detecção de objetos.
Visualizar Anotações do Conjunto de Dados
Esta função visualiza as anotações YOLO em uma imagem antes do treinamento, ajudando a identificar e corrigir quaisquer anotações incorretas que possam levar a resultados de detecção incorretos. Ela desenha caixas delimitadoras, rotula objetos com nomes de classe e ajusta a cor do texto com base na luminância do fundo para melhor legibilidade.
from ultralytics.data.utils import visualize_image_annotations
label_map = { # Define the label map with all annotated class labels.
0: "person",
1: "car",
}
# Visualize
visualize_image_annotations(
"path/to/image.jpg", # Input image path.
"path/to/annotations.txt", # Annotation file path for the image.
label_map,
)
Converter Máscaras de Segmentação para o Formato YOLO
Use isto para converter um dataset de imagens de máscara de segmentação para o formato de segmentação Ultralytics YOLO. Esta função recebe o diretório contendo as imagens de máscara em 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
# 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)
Converter COCO para o Formato YOLO
Use isto para converter COCO anotações JSON para o formato YOLO. Para conjuntos de dados de detecção de objetos (caixa delimitadora), defina ambos use_segments
e use_keypoints
para False
.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para obter informações adicionais sobre a convert_coco
função, visite 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("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(f"Bounding Box Width {width.item()}, Height {height.item()}, Area {area.item()}")
Converter Caixas Delimitadoras em Segmentos
Com os x y w h
dados de caixa delimitadora existentes, converta para segmentos usando a yolo_bbox2segment
função. Organize os arquivos para 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, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)
Visite a yolo_bbox2segment
página de referência para obter mais informações sobre a função.
Converter Segmentos em Caixas Delimitadoras
Se você tiver um conjunto de dados que usa o formato de conjunto de dados de segmentação,, você pode convertê-los facilmente em caixas delimitadoras verticais (ou horizontais) (x y w h
formato) com esta função.
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
Para entender como esta função funciona, visite a página de referência.
Utilitários
Compressão de Imagem
Comprime um único arquivo de imagem para um tamanho reduzido, preservando sua proporção e 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 do Conjunto de Dados
Divide automaticamente um conjunto de dados em train
/val
/test
divisões e salva as divisões resultantes em autosplit_*.txt
arquivos. Esta função usa amostragem aleatória, que é excluída ao usar o fraction
argumento para treinamento.
from ultralytics.data.utils import autosplit
autosplit(
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
)
Consulte a página de referência para obter detalhes adicionais sobre esta função.
Segmento-polígono para Máscara Binária
Converter um único polígono (como uma lista) em uma máscara binária do tamanho de imagem especificado. O polígono deve estar na forma de [N, 2]
, onde N
é o número de (x, y)
pontos 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]) # (238, 2)
mask = polygon2mask(
imgsz, # tuple
[polygon], # input as list
color=255, # 8-bit binary
downsample_ratio=1,
)
Caixas Delimitadoras
Instâncias de Caixa Delimitadora (Horizontal)
Para gerenciar dados de caixa delimitadora, a Bboxes
A classe ajuda a converter entre formatos de coordenadas de caixa, dimensionar as dimensões da caixa, calcular áreas, incluir offsets 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]]
# )
Veja o arquivo Bboxes
seção de referência para obter mais atributos e métodos.
Dica
Muitas das seguintes funções (e mais) podem ser acessadas usando a Bboxes
classe, mas se preferir trabalhar diretamente com as funções, consulte as próximas subseções para saber como importá-las independentemente.
Escalonamento de Caixas
Ao aumentar ou diminuir a escala de uma imagem, você pode dimensionar adequadamente as coordenadas da caixa delimitadora correspondentes para corresponder 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)
# >>> 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 Caixa Delimitadora
XYXY → XYWH
Converter as coordenadas da caixa delimitadora do formato (x1, y1, x2, y2) para o formato (x, y, largura, altura), onde (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 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
Consulte a docstring para cada função ou visite a ultralytics.utils.ops
página de referência para ler mais.
Plotagem
Desenhando Anotações
Ultralytics inclui um Annotator
classe para anotar vários tipos de dados. É melhor utilizada com caixas delimitadoras de detecção de objetos, pontos-chave de pose, e caixas delimitadoras orientadas.
Anotação de Sweep da Ultralytics
Exemplos Python usando Ultralytics YOLO 🚀
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="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, _, 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 detalhes adicionais sobre o sweep_annotator
método em nossa seção de referência aqui.
Bounding Boxes Horizontais
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
quando trabalhar com resultados de detecção.
Caixas Delimitadoras Orientadas (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()
Anotação de Círculo de Caixas Delimitadoras Rótulo de Círculo
Assista: Guia Detalhado para Anotações de Texto e Círculo com Demos ao Vivo em Python | Anotações Ultralytics 🚀
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo11s.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)
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)], color=colors(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()
Anotação de Texto em Caixas Delimitadoras Rótulo de Texto
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo11s.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 text 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)
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)], color=colors(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()
Veja o arquivo Annotator
Página de Referência para obter informações adicionais.
Diversos
Perfil de Código
Verifique a duração para o código ser executado/processado usando with
ou como um decorator.
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"
Formatos Suportados pela Ultralytics
Precisa usar programaticamente os formatos de imagem ou vídeo suportados em Ultralytics? Use estas constantes, se necessário:
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'}
Tornar Divisível
Calcule o número inteiro mais próximo de x
que seja uniformemente divisível por y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8
FAQ
Quais utilitários estão incluídos no pacote Ultralytics para aprimorar os fluxos de trabalho de aprendizado de máquina?
O pacote Ultralytics inclui utilitários projetados para otimizar os fluxos de trabalho de machine learning. Os principais utilitários incluem auto-anotação para rotular conjuntos de dados, converter COCO para o formato YOLO com convert_coco, comprimir imagens e divisão automática de conjuntos de dados. Essas ferramentas reduzem o esforço manual, garantem a consistência e aumentam a eficiência do processamento de dados.
Como posso usar Ultralytics para rotular automaticamente meu conjunto de dados?
Se você tiver um modelo de detecção de objetos Ultralytics YOLO pré-treinado, poderá usá-lo com o modelo SAM para auto-anotar seu 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="yolo11n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)
Para mais detalhes, consulte a seção de referência auto_annotate.
Como faço para converter anotações de conjunto de dados COCO para o formato YOLO na Ultralytics?
Para converter anotações COCO JSON para o formato YOLO para detecção de objetos, você pode usar o convert_coco
utilitário. Aqui está um trecho de código de exemplo:
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para obter informações adicionais, visite a página de referência convert_coco.
Qual é o propósito do YOLO Data Explorer no pacote Ultralytics?
O YOLO Explorer é uma ferramenta poderosa introduzida na 8.1.0
atualização para aprimorar a compreensão do conjunto de dados. Ele permite que você use consultas de texto para encontrar instâncias de objetos em seu conjunto de dados, facilitando a análise e o gerenciamento de seus dados. Esta ferramenta fornece informações valiosas sobre a composição e distribuição do conjunto de dados, ajudando a melhorar o treinamento e o desempenho do modelo.
Como posso converter bounding boxes em segmentos na Ultralytics?
Para converter dados de caixa delimitadora existentes (no formato x y w h
formato) em segmentos, você pode usar a yolo_bbox2segment
função. Certifique-se de que seus arquivos estejam organizados com 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, # saved to "labels-segment" in the images directory
sam_model="sam_b.pt",
)
Para obter mais informações, visite a página de referência yolo_bbox2segment.