Utilitários simples
O ultralytics
O pacote Ultralytics fornece uma variedade de utilitários para apoiar, melhorar e acelerar os seus fluxos de trabalho. Embora existam muitos mais disponíveis, este guia destaca alguns dos mais úteis para os programadores, servindo de referência prática para a programação com ferramentas Ultralytics .
Ver: Ultralytics Utilitários | Anotação automática, API do explorador e conversão de conjuntos de dados
Dados
Etiquetagem automática / Anotações
A anotação de conjuntos de dados é um processo que consome muitos recursos e tempo. Se tiver um modelo dedeteção de objectos Ultralytics YOLO treinado com uma quantidade razoável de dados, pode utilizá-lo com o SAM para anotar automaticamente 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 devolve qualquer valor. Para mais pormenores:
- Ver o secção de referência para
annotator.auto_annotate
para obter mais informações sobre o funcionamento da função. - Utilizar em combinação com o função
segments2boxes
para gerar também caixas delimitadoras de deteção de objectos.
Visualizar anotações de conjuntos de dados
Esta função visualiza YOLO anotações numa imagem antes do treino, ajudando a identificar e corrigir quaisquer anotações erradas que possam levar a resultados de deteção incorrectos. Desenha caixas delimitadoras, rotula objectos com nomes de classes e ajusta a cor do texto com base na luminância do fundo para uma 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
Utilize esta opção para converter um conjunto de dados de imagens de máscara de segmentação para o Ultralytics YOLO do Ultralytics. Esta função utiliza o diretório que contém as imagens de máscara de formato binário e converte-as para o formato de segmentação YOLO .
As máscaras convertidas serão guardadas 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
Utilize isto para converter COCO anotações JSON no formato YOLO . Para conjuntos de dados de deteção de objectos (caixa delimitadora), defina ambos use_segments
e use_keypoints
para False
.
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para mais informações sobre o convert_coco
função, visitar 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 actuais x y w h
dados da caixa delimitadora, converter em segmentos utilizando o yolo_bbox2segment
função. Organize os ficheiros 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 o yolo_bbox2segment
página de referência para mais informações sobre a função.
Converter segmentos em caixas delimitadoras
Se tiver um conjunto de dados que utilize o formato do conjunto de dados de segmentação, pode facilmente convertê-las 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 compreender o funcionamento desta função, visite a página de referência.
Utilidades
Compressão de imagem
Comprime um único ficheiro de imagem para um tamanho reduzido, preservando a sua relação de aspeto e qualidade. Se a imagem de entrada for mais pequena do que a dimensão máxima, 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)
Conjunto de dados de divisão automática
Dividir automaticamente um conjunto de dados em train
/val
/test
e guardar as divisões resultantes em autosplit_*.txt
ficheiros. Esta função utiliza a amostragem aleatória, que é excluída quando se utiliza a função fraction
argumento para a formação.
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 Referência para obter mais informações sobre esta função.
Segmento-polígono para máscara binária
Converte um único polígono (como uma lista) numa máscara binária com o tamanho de imagem especificado. O polígono deve ter a forma de [N, 2]
, em que N
é o número de (x, y)
pontos que definem o contorno do polígono.
Aviso
N
deve sempre ser uniforme.
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 de delimitação
Instâncias de caixa delimitadora (horizontal)
Para gerir os dados da caixa delimitadora, o Bboxes
A classe ajuda a converter entre formatos de coordenadas de caixa, dimensionar dimensões de caixa, 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]]
# )
Ver o Bboxes
secção de referência para mais atributos e métodos.
Dica
Muitas das seguintes funções (e outras) podem ser acedidas utilizando a função Bboxes
classemas se preferir trabalhar diretamente com as funções, consulte as subsecções seguintes para saber como as importar independentemente.
Caixas de escala
Ao dimensionar uma imagem para cima ou para baixo, pode dimensionar adequadamente as coordenadas da caixa delimitadora correspondente para corresponder utilizando 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
Converte 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 caixa delimitadora
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
Veja a documentação de cada função ou visite a página ultralytics.utils.ops
página de referência para ler mais.
Plotagem
Anotações de desenho
Ultralytics inclui um Annotator
para anotar vários tipos de dados. É melhor utilizada com caixas delimitadoras de deteção de objectos, pontos-chave da posee caixas delimitadoras orientadas.
Ultralytics Anotação de varrimento
Exemplos Python utilizando o Ultralytics YOLO 🚀
import cv2
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, y, flags, param): # Mouse callback for dragging line.
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.
annotator = SolutionAnnotator(im0)
results = model.track(im0, persist=True) # Track objects using track method.
if f == 1:
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, drag_line)
if results[0].boxes.id is not None:
if results[0].masks is not None:
masks = results[0].masks.xy
track_ids = results[0].boxes.id.int().cpu().tolist()
clss = results[0].boxes.cls.cpu().tolist()
boxes = results[0].boxes.xyxy.cpu()
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.
if mask is not None and mask.size > 0:
# If you want to overlay the masks
# mask[:, 0] = np.clip(mask[:, 0], line_x, w)
# mask_img = cv2.fillPoly(im0.copy(), [mask.astype(int)], color)
# cv2.addWeighted(mask_img, 0.5, im0, 0.5, 0, im0)
if box[0] > line_x:
count += 1
annotator.seg_bbox(mask=mask, mask_color=color, label=str(classes[cls]))
else:
if box[0] > line_x:
count += 1
annotator.box_label(box=box, color=color, label=str(classes[cls]))
annotator.sweep_annotator(line_x=line_x, line_y=h, label=f"COUNT:{count}") # Display the sweep
cv2.imshow(window_name, im0)
video_writer.write(im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release() # Release the video capture.
video_writer.release() # Release the video writer.
cv2.destroyAllWindows() # Destroy all opened windows.
Caixas delimitadoras 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 utilizados a partir de model.names
quando trabalhar com resultados de deteçã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()
Caixas de contorno Anotação de círculo Etiqueta de círculo
Ver: Guia detalhado para anotações de texto e círculos com Python Demonstrações em direto | Ultralytics Anotações 🚀
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()
Caixas de contorno Anotação de texto Etiqueta 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()
Ver o Annotator
Página de referência para mais informações.
Diversos
Perfilamento de código
Verificar a duração da execução/processamento do código utilizando with
ou como decorador.
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 Formatos suportados
Precisa de utilizar de forma programática os formatos de imagem ou vídeo suportados no Ultralytics? Utilize 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
Calcular o número inteiro mais próximo de x
que é divisível equitativamente por y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8
FAQ
Que utilitários estão incluídos no pacote Ultralytics para melhorar os fluxos de trabalho de aprendizagem automática?
O pacote Ultralytics inclui utilitários concebidos para simplificar e otimizar os fluxos de trabalho de aprendizagem automática. Os principais utilitários incluem a anotação automática para rotular conjuntos de dados, converter o formato COCO para YOLO com convert_coco, comprimir imagens e dividir automaticamente o conjunto de dados. Essas ferramentas reduzem o esforço manual, garantem a consistência e aumentam a eficiência do processamento de dados.
Como é que posso utilizar Ultralytics para etiquetar automaticamente o meu conjunto de dados?
Se tiver um modelo de deteção de objectos pré-treinado em Ultralytics YOLO , pode utilizá-lo com o modelo SAM para anotar automaticamente o seu conjunto de dados em 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 informações, consulte a secção de referência auto_annotate.
Como é que converto as anotações do conjunto de dados COCO para o formato YOLO em Ultralytics?
Para converter as anotações COCO JSON no formato YOLO para deteção de objectos, pode utilizar o convert_coco
utilitário. Aqui está um exemplo de trecho de código:
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para mais informações, visite a página de referência do convert_coco.
Qual é o objetivo do explorador de dados YOLO no pacote Ultralytics ?
O YOLO Explorador é uma ferramenta poderosa introduzida no 8.1.0
para melhorar a compreensão do conjunto de dados. Permite-lhe utilizar consultas de texto para encontrar instâncias de objectos no seu conjunto de dados, facilitando a análise e a gestão dos seus dados. Esta ferramenta fornece informações valiosas sobre a composição e distribuição do conjunto de dados, ajudando a melhorar a formação e o desempenho do modelo.
Como é que posso converter caixas delimitadoras em segmentos em Ultralytics?
Para converter dados de caixa delimitadora existentes (em x y w h
) para segmentos, é possível utilizar o yolo_bbox2segment
função. Certifique-se de que os seus ficheiros estão organizados com diretórios separados para imagens e etiquetas.
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ênciayolo_bbox2segment.