Utilidades sencillas
En ultralytics
viene con una miríada de utilidades que pueden apoyar, mejorar y acelerar tus flujos de trabajo. Hay muchas más disponibles, pero aquí tienes algunas que serán útiles para la mayoría de los desarrolladores. También son un gran punto de referencia para utilizar cuando se aprende a programar.
Observa: Ultralytics Utilidades | Anotación automática, API del Explorador y Conversión de conjuntos de datos
Datos
YOLO Explorador de datos
YOLO Explorador se añadió en el 8.1.0
aniversario y es una potente herramienta que puedes utilizar para comprender mejor tu conjunto de datos. Una de las funciones clave que ofrece YOLO Explorer es la posibilidad de utilizar consultas de texto para encontrar instancias de objetos en tu conjunto de datos.
Autoetiquetado / Anotaciones
La anotación de conjuntos de datos es un proceso que consume muchos recursos y tiempo. Si tienes un modelo de detección de objetos YOLO entrenado en una cantidad razonable de datos, puedes utilizarlo y SAM para autoanotar datos adicionales (formato de segmentación).
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",
)
-
Esta función no devuelve nada
-
Consulta la sección de referencia para
annotator.auto_annotate
para más información sobre el funcionamiento de la función. -
Utilízalo en combinación con el función
segments2boxes
para generar también cuadros delimitadores de detección de objetos
Convierte COCO al formato YOLO
Se utiliza para convertir las anotaciones COCO JSON al formato adecuado YOLO . Para conjuntos de datos de detección de objetos (cuadro delimitador), use_segments
y use_keypoints
deben ser False
from ultralytics.data.converter import convert_coco
convert_coco(#(1)!
'../datasets/coco/annotations/',
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
- Esta función no devuelve nada
Para más información sobre el convert_coco
función, visita la página de referencia
Obtener dimensiones del cuadro delimitador
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()))
Convertir cuadros delimitadores en segmentos
Con las x y w h
datos del cuadro delimitador, conviértelos en segmentos utilizando la función yolo_bbox2segment
función. Los archivos de imágenes y anotaciones deben organizarse así:
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"
)
- Esta función no devuelve nada
Visita la página yolo_bbox2segment
página de referencia para más información sobre la función.
Convertir segmentos en cuadros delimitadores
Si tienes un conjunto de datos que utiliza la función formato del conjunto de datos de segmentación puedes convertirlos fácilmente en cuadros delimitadores arriba-derecha (u horizontales) (x y w h
formato) con esta función.
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 cómo funciona esta función, visita la página de referencia
Utilidades
Compresión de imágenes
Comprime un único archivo de imagen a un tamaño reducido, conservando su relación de aspecto y calidad. Si la imagen de entrada es menor que la dimensión máxima, no se redimensionará.
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)!
- Esta función no devuelve nada
Dividir automáticamente el conjunto de datos
Dividir automáticamente un conjunto de datos en train
/val
/test
y guarda las divisiones resultantes en autosplit_*.txt
archivos. Esta función utilizará el muestreo aleatorio, que no se incluye cuando se utiliza fraction
argumento para la formación.
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
)
- Esta función no devuelve nada
Consulta la página Referencia para obtener más detalles sobre esta función.
Segmento-polígono a máscara binaria
Convierte un único polígono (en forma de lista) en una máscara binaria del tamaño de imagen especificado. Polígono en forma de [N, 2]
con N
como el número de (x, y)
puntos que definen el contorno del polígono.
Advertencia
N
debe siempre 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
)
Cajas delimitadoras
Cuadro delimitador (horizontal) Instancias
Para gestionar los datos de los recuadros delimitadores, la función Bboxes
te ayudará a convertir entre formatos de coordenadas de cajas, escalar las dimensiones de las cajas, calcular áreas, incluir desplazamientos, ¡y mucho más!
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]]
)
Ver el Bboxes
sección de referencia para ver más atributos y métodos disponibles.
Consejo
Se puede acceder a muchas de las siguientes funciones (y a otras más) utilizando la función Bboxes
clase pero si prefieres trabajar con las funciones directamente, consulta las siguientes subsecciones sobre cómo importarlas de forma independiente.
Cajas de Escala
Al escalar una imagen hacia arriba o hacia abajo, las coordenadas correspondientes del cuadro delimitador pueden escalarse adecuadamente para que coincidan 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,
)
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]]
)
- Cajas delimitadoras escaladas para el nuevo tamaño de la imagen
Conversiones de formato de cuadro delimitador
XYXY → XYWH
Convierte las coordenadas de la caja delimitadora del formato (x1, y1, x2, y2) al formato (x, y, anchura, altura) donde (x1, y1) es la esquina superior izquierda y (x2, y2) es la esquina inferior derecha.
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]]
)
Todas las conversiones del cuadro delimitador
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
Consulta el docstring de cada función o visita la página ultralytics.utils.ops
página de referencia para leer más sobre cada función.
Trazando
Anotaciones de dibujo
Ultralytics incluye una clase Anotador que puede utilizarse para anotar cualquier tipo de datos. Es más fácil de usar con cuadros delimitadores de detección de objetos, puntos clave de pose y cuadros delimitadores orientados.
Cuadros delimitadores horizontales
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()
- Se pueden utilizar nombres de
model.names
cuando trabajar con los resultados de la detección
Cajas 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"{names.get(int(c_idx))}"
ann.box_label(
obb,
label,
color=colors(c_idx, True),
rotated=True,
)
image_with_obb = ann.result()
Ver el Annotator
Página de referencia para obtener más información.
Varios
Perfiles de código
Comprueba la duración para que el código se ejecute/procese utilizando with
o como decorador.
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 Formatos admitidos
¿Quieres o necesitas utilizar los formatos de los tipos de imágenes o vídeos admitidos por Ultralytics mediante programación? Utiliza estas constantes si lo necesitas.
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')
Hacer divisible
Calcula el número entero más próximo a x
para que sea divisible al dividirlo por y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
>>> 9
make_divisible(7, 2)
>>> 8