Utilitários simples
O ultralytics
vem com uma miríade de utilitários que podem apoiar, melhorar e acelerar os teus fluxos de trabalho. Existem muitos mais disponíveis, mas aqui estão alguns que serão úteis para a maioria dos programadores. São também um ótimo ponto de referência para usares quando estiveres a aprender a programar.
Observa: Ultralytics Utilitários | Anotação automática, API do explorador e conversão de conjuntos de dados
Dados
YOLO Explorador de dados
YOLO Explorador foi adicionado no 8.1.0
é uma ferramenta poderosa que pode utilizar para compreender melhor o seu conjunto de dados. Uma das principais funções que o YOLO Explorer fornece é a capacidade de utilizar consultas de texto para encontrar instâncias de objectos no seu conjunto de dados.
Etiquetagem automática / Anotações
A anotação de conjuntos de dados é um processo que consome muitos recursos e tempo. Se tiveres um modelo de deteção de objectos YOLO treinado com uma quantidade razoável de dados, podes utilizá-lo e SAM para anotar automaticamente dados adicionais (formato de segmentação).
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",
)
-
Não devolve nada desta função
-
Consulta a secção de referência para
annotator.auto_annotate
para saberes mais sobre o funcionamento da função. -
Utiliza em combinação com o função
segments2boxes
para gerar caixas delimitadoras de deteção de objectos, bem como
Converte COCO para o formato YOLO
Utiliza para converter anotações COCO JSON no formato YOLO adequado. Para conjuntos de dados de deteção de objectos (caixa delimitadora), use_segments
e use_keypoints
devem ser ambos False
from ultralytics.data.converter import convert_coco
convert_coco( # (1)!
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
- Não devolve nada desta função
Para mais informações sobre o convert_coco
função, visita a página de referência
Obtém as dimensões da caixa delimitadora
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()))
Converter caixas delimitadoras em segmentos
Com os actuais x y w h
dados da caixa delimitadora, converte para segmentos utilizando o yolo_bbox2segment
Funciona. Os ficheiros para imagens e anotações têm de ser organizados desta 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( # (1)!
im_dir="path/to/images",
save_dir=None, # saved to "labels-segment" in images directory
sam_model="sam_b.pt",
)
- Não devolve nada desta função
Visita a yolo_bbox2segment
página de referência para obteres mais informações sobre esta função.
Converter segmentos em caixas delimitadoras
Se tiveres um conjunto de dados que utilize o formato do conjunto de dados de segmentação podes facilmente convertê-las em caixas delimitadoras para cima e para a direita (ou horizontais) (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, ..., 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 compreenderes o funcionamento desta função, visita a página de referência
Utilidades
Compressão de imagens
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) # (1)!
- Não devolve nada desta função
Auto-split Dataset
Divide automaticamente um conjunto de dados em train
/val
/test
divide e guarda as divisões resultantes em autosplit_*.txt
ficheiros. Esta função utiliza a amostragem aleatória, que não está incluída quando utilizas fraction
argumento para a formação.
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
)
- Não devolve nada desta função
Consulta a página Referência para obteres mais informações sobre esta função.
Segmento-polígono para máscara binária
Converte um único polígono (como lista) para uma máscara binária do tamanho de imagem especificado. Converte um polígono na forma de [N, 2]
com N
como o número de (x, y)
pontos que definem o contorno do polígono.
Aviso
N
deves sempre fica equilibrado.
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, a função Bboxes
A classe ajuda-te a converter entre formatação 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]]
# )
Vê o Bboxes
secção de referência para conheceres mais atributos e métodos disponíveis.
Dica
Muitas das seguintes funções (e mais) podem ser acedidas utilizando a função Bboxes
classe mas se preferires trabalhar com as funções diretamente, vê nas próximas subsecções como importá-las independentemente.
Caixas de escala
Ao aumentar ou diminuir a escala de uma imagem, as coordenadas da caixa delimitadora correspondentes podem ser adequadamente dimensionadas 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) # (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]]
# )
- Caixas de contorno escaladas para o novo tamanho de imagem
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
Vê a documentação de cada função ou visita a página ultralytics.utils.ops
página de referência para leres mais sobre cada função.
Traçar
Anotações de desenho
Ultralytics inclui uma classe Annotator que pode ser utilizada para anotar qualquer tipo de dados. É mais fácil de utilizar com caixas delimitadoras de deteção de objectos, pontos-chave de pose e caixas delimitadoras orientadas.
Caixas de limite horizontais
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()
- 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 delimitadoras Anotação de círculo(etiqueta de círculo)
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()
Anotação de texto das caixas delimitadoras(etiqueta de texto)
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()
Vê o Annotator
Página de referência para obteres mais informações.
Diversos
Perfil do código
Verifica a duração do código a executar/processar 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
Queres ou precisas de utilizar os formatos dos tipos de imagens ou vídeos suportados por Ultralytics de forma programática? Utiliza estas constantes se precisares.
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'}
Torna-o divisível
Calcula o número inteiro mais próximo de x
para tornar divisível por igual quando dividido 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 uma variedade de 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. Estas ferramentas têm como objetivo reduzir o esforço manual, garantir a consistência e melhorar a eficiência do processamento de dados.
Como posso utilizar Ultralytics para etiquetar automaticamente o meu conjunto de dados?
Se tiveres um modelo de deteção de objectos pré-treinado em Ultralytics YOLO , podes utilizá-lo com o modelo SAM para anotar automaticamente o teu conjunto de dados em formato de segmentação. Vê um exemplo:
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",
)
Para mais detalhes, consulta 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, podes utilizar o convert_coco
utilitário. Aqui tens um exemplo de um fragmento 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, visita 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-te utilizar consultas de texto para encontrar instâncias de objectos no teu conjunto de dados, facilitando a análise e a gestão dos teus 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, podes usar o yolo_bbox2segment
Funciona. Certifica-te de que os teus ficheiros estão organizados com directó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, visita a página de referênciayolo_bbox2segment.
Criado em 2024-02-20, Atualizado em 2024-07-04
Autores: glenn-jocher (9), ambitious-octopus (1), IvorZhu331 (1), RizwanMunawar (1), Burhan-Q (2)