Utilidades sencillas
En ultralytics
proporciona una variedad de utilidades para apoyar, mejorar y acelerar sus flujos de trabajo. Aunque hay muchas más disponibles, esta guía destaca algunas de las más útiles para los desarrolladores, sirviendo como referencia práctica para programar con las herramientas Ultralytics .
Observa: Ultralytics Utilidades | Anotación automática, API Explorer y conversión de conjuntos de datos
Datos
Autoetiquetado / Anotaciones
La anotación de conjuntos de datos es un proceso que consume muchos recursos y tiempo. Si dispone de un modelo dedetección de objetosYOLO Ultralytics entrenado con una cantidad razonable de datos, puede utilizarlo con SAM para anotación automática de datos adicionales en formato de segmentación.
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 función no devuelve ningún valor. Para más detalles:
- Véase el sección de referencia para
annotator.auto_annotate
para saber más sobre el funcionamiento de esta función. - Utilizar en combinación con el función
segments2boxes
para generar también cuadros delimitadores de detección de objetos.
Visualizar anotaciones de conjuntos de datos
Esta función visualiza las anotaciones de YOLO en una imagen antes del entrenamiento, ayudando a identificar y corregir cualquier anotación errónea que pudiera conducir a resultados de detección incorrectos. Dibuja cuadros delimitadores, etiqueta los objetos con nombres de clase y ajusta el color del texto en función de la luminancia del fondo para mejorar la legibilidad.
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,
)
Convertir máscaras de segmentación en formato YOLO
Utilícelo para convertir un conjunto de datos de imágenes de máscaras de segmentación al formato Ultralytics YOLO de Ultralytics. Esta función toma el directorio que contiene las imágenes de máscara en formato binario y las convierte al formato de segmentación YOLO .
Las máscaras convertidas se guardarán en el directorio de salida 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)
Convertir COCO en formato YOLO
Utilícelo para convertir COCO JSON en el formato YOLO . Para los conjuntos de datos de detección de objetos (cuadro delimitador), configure ambos use_segments
y use_keypoints
a False
.
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para más información sobre el convert_coco
función, visite la página de referencia.
Obtener las dimensiones del cuadro delimitador
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()}")
Convertir cuadros delimitadores en segmentos
Con los x y w h
convertir a segmentos mediante la función yolo_bbox2segment
función. Organice los archivos de imágenes y anotaciones de la siguiente manera:
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 el yolo_bbox2segment
página de referencia para más información sobre la función.
Convertir segmentos en cuadros delimitadores
Si tiene un conjunto de datos que utiliza la función formato del conjunto de datos de segmentaciónpuede convertirlos fácilmente en cuadros delimitadores verticales (u horizontales) (x y w h
formato) con esta función.
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 cómo funciona esta función, visite la página de referencia.
Servicios
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)
Dividir automáticamente el conjunto de datos
Dividir automáticamente un conjunto de datos en train
/val
/test
y guardar las divisiones resultantes en autosplit_*.txt
archivos. Esta función utiliza el muestreo aleatorio, que se excluye cuando se utiliza la función fraction
argumento a favor de la formación.
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 la página Referencia para obtener más información 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. El polígono debe tener la forma [N, 2]
donde N
es el número de (x, y)
puntos que definen el contorno del polígono.
Advertencia
N
siempre debe 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
Instancias de cuadro delimitador (horizontal)
Para gestionar los datos de los recuadros delimitadores, el Bboxes
ayuda a convertir entre formatos de coordenadas de cajas, escalar dimensiones de cajas, calcular áreas, incluir desplazamientos, etc.
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éase el Bboxes
sección de referencia para más atributos y métodos.
Consejo
Se puede acceder a muchas de las siguientes funciones (y a otras más) mediante la función Bboxes
clasepero si prefiere trabajar directamente con las funciones, consulte las subsecciones siguientes para saber cómo importarlas de forma independiente.
Cajas de escala
Al escalar una imagen hacia arriba o hacia abajo, puede escalar adecuadamente las coordenadas correspondientes del cuadro delimitador 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,
)
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]]
# )
Conversiones de formato de cuadro delimitador
XYXY → XYWH
Convierte las coordenadas del cuadro delimitador 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)
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 las conversiones 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 la documentación de cada función o visite la página ultralytics.utils.ops
página de referencia para leer más.
Trazado
Anotaciones de dibujo
Ultralytics incluye un Annotator
para anotar varios tipos de datos. Se utiliza mejor con detección de objetos cuadros delimitadores, plantear puntos clavey cuadros delimitadores orientados.
Ultralytics Anotación de barrido
Ejemplos Python utilizando 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.
Cuadros delimitadores horizontales
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()
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"{obb_names.get(int(c_idx))}"
ann.box_label(
obb,
label,
color=colors(c_idx, True),
rotated=True,
)
image_with_obb = ann.result()
Cuadros delimitadores Anotación circular Etiqueta circular
Observa: Guía en profundidad de anotaciones de texto y círculos con Python Demostraciones en directo | Ultralytics Anotaciones 🚀
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()
Cuadros delimitadores Texto Anotación Texto Etiqueta
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()
Véase el Annotator
Página de referencia para más información.
Varios
Perfiles de código
Compruebe la duración de la ejecución/procesamiento del código mediante with
o 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 admitidos
¿Necesita utilizar mediante programación los formatos de imagen o vídeo admitidos en Ultralytics? Utilice estas constantes si es necesario:
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'}
Hacer divisible
Calcular el número entero más próximo a x
que sea divisible en partes iguales por y
.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8
PREGUNTAS FRECUENTES
¿Qué utilidades se incluyen en el paquete Ultralytics para mejorar los flujos de trabajo de aprendizaje automático?
El paquete Ultralytics incluye utilidades diseñadas para agilizar y optimizar los flujos de trabajo de aprendizaje automático. Entre las principales utilidades se incluyen la anotación automática para etiquetar conjuntos de datos, la conversión de formato COCO a YOLO con convert_coco, la compresión de imágenes y la división automática de conjuntos de datos. Estas herramientas reducen el esfuerzo manual, garantizan la coherencia y mejoran la eficiencia del procesamiento de datos.
¿Cómo puedo utilizar Ultralytics para autoetiquetar mi conjunto de datos?
Si dispone de un modelo de detección de objetos preentrenado en Ultralytics YOLO , puede utilizarlo con el modelo SAM para auto-anotar su conjunto de datos en formato de segmentación. He aquí un ejemplo:
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 más detalles, consulte la sección de referencia de auto_annotate.
¿Cómo convierto las anotaciones del conjunto de datos COCO al formato YOLO en Ultralytics?
Para convertir las anotaciones JSON de COCO al formato YOLO para la detección de objetos, puede utilizar la función convert_coco
utilidad. He aquí un fragmento de código de ejemplo:
from ultralytics.data.converter import convert_coco
convert_coco(
"../datasets/coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)
Para más información, visite la página de referencia de convert_coco.
¿Para qué sirve el explorador de datos YOLO del paquete Ultralytics ?
En YOLO Explorador es una potente herramienta introducida en el 8.1.0
para mejorar la comprensión del conjunto de datos. Permite utilizar consultas de texto para encontrar instancias de objetos en el conjunto de datos, lo que facilita el análisis y la gestión de los datos. Esta herramienta proporciona información valiosa sobre la composición y distribución del conjunto de datos, lo que ayuda a mejorar la formación y el rendimiento del modelo.
¿Cómo puedo convertir cuadros delimitadores en segmentos en Ultralytics?
Para convertir los datos de los recuadros delimitadores existentes (en x y w h
) a segmentos, puede utilizar el yolo_bbox2segment
función. Asegúrese de que sus archivos están organizados con directorios separados para imágenes y 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 más información, visite la página de referenciayolo_bbox2segment.