Utilidades simples
El paquete ultralytics proporciona una variedad de utilidades para apoyar, mejorar y acelerar tus flujos de trabajo. Aunque hay muchas más disponibles, esta guía destaca algunas de las más útiles para los desarrolladores, sirviendo como una referencia práctica para programar con las herramientas de Ultralytics.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
Datos
Etiquetado / Anotaciones automáticas
La anotación de conjuntos de datos es un proceso que consume mucho tiempo y recursos. Si tienes un modelo de detección de objetos Ultralytics YOLO entrenado con una cantidad razonable de datos, puedes usarlo con SAM para auto-anotar datos adicionales en formato de segmentación.
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.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:
- Consulta la sección de referencia para
annotator.auto_annotatepara obtener más información sobre cómo funciona la función. - Úsala en combinación con la función
segments2boxespara generar también cuadros delimitadores de detección de objetos.
Visualizar anotaciones del conjunto de datos
Esta función visualiza las anotaciones YOLO en una imagen antes del entrenamiento, lo que ayuda a identificar y corregir cualquier anotación incorrecta que pueda conducir a resultados de detección erróneos. Dibuja cuadros delimitadores, etiqueta objetos con nombres de clases y ajusta el color del texto según 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 al formato YOLO

Utiliza esto para convertir un conjunto de datos de imágenes de máscara de segmentación al formato de segmentación de Ultralytics YOLO. 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 al formato YOLO
Utiliza esto para convertir anotaciones JSON de COCO al formato YOLO. Para conjuntos de datos de detección de objetos (cuadros delimitadores), establece tanto use_segments como use_keypoints en False.
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)Para obtener información adicional sobre la función convert_coco, visita la página de referencia.
Obtener dimensiones del cuadro delimitador
import cv2
from ultralytics import YOLO
from ultralytics.utils.plotting import Annotator
model = YOLO("yolo26n.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 a segmentos
Con datos de cuadros delimitadores existentes en formato x y w h, conviértelos a segmentos usando la función yolo_bbox2segment. Organiza los archivos para imágenes y anotaciones de la siguiente manera:
data
|__ images
├─ 001.jpg
├─ 002.jpg
├─ ..
└─ NNN.jpg
|__ labels
├─ 001.txt
├─ 002.txt
├─ ..
└─ NNN.txtfrom 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",
)Visita la página de referencia de yolo_bbox2segment para obtener más información sobre la función.
Convertir segmentos a cuadros delimitadores
Si tienes un conjunto de datos que utiliza el formato de conjunto de datos de segmentación, puedes convertirlos fácilmente a cuadros delimitadores rectos (o horizontales) (formato x y w h) 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 boxesPara entender cómo funciona esta función, visita la página de referencia.
Utilidades
Compresión de imágenes
Comprime un solo archivo de imagen a un tamaño reducido manteniendo su relación de aspecto y calidad. Si la imagen de entrada es más pequeña 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)División automática de conjuntos de datos
Divide automáticamente un conjunto de datos en particiones de train/val/test y guarda los resultados en archivos autosplit_*.txt. Esta función utiliza muestreo aleatorio, el cual se excluye al usar el argumento fraction para el entrenamiento.
from ultralytics.data.split 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
)Consulta la página de referencia para detalles adicionales sobre esta función.
Segmento-polígono a máscara binaria
Convierte un solo polígono (como lista) a 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 puntos (x, y) que definen el contorno del polígono.
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,
)Cuadros delimitadores
Instancias de cuadros delimitadores (horizontales)
Para gestionar datos de cuadros delimitadores, la clase Bboxes ayuda a convertir entre formatos de coordenadas de caja, escalar dimensiones de caja, calcular áreas, incluir desplazamientos y más.
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]]
# )Consulta la sección de referencia de Bboxes para más atributos y métodos.
Muchas de las siguientes funciones (y más) pueden ser accedidas usando la clase Bboxes, pero si prefieres trabajar con las funciones directamente, mira las siguientes subsecciones sobre cómo importarlas independientemente.
Escalar cajas
Al escalar una imagen hacia arriba o hacia abajo, puedes escalar adecuadamente las coordenadas correspondientes del cuadro delimitador para que coincidan 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]]
# )Conversiones de formato de cuadros delimitadores
XYXY → XYWH
Convierte las coordenadas del cuadro delimitador del formato (x1, y1, x2, y2) al formato (x, y, ancho, 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 cuadros delimitadores
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 docstringsSee the docstring for each function or visit the ultralytics.utils.ops reference page to read more.
Graficado
Utilidades de anotación
Ultralytics incluye una clase Annotator para anotar varios tipos de datos. Es mejor usarla con cuadros delimitadores de detección de objetos, puntos clave de pose y cuadros delimitadores orientados.
Anotación de cajas
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()Los nombres se pueden usar desde model.names al trabajar con resultados de detección. También consulta la página de referencia de Annotator para información adicional.
Anotación de barrido de Ultralytics
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="yolo26s-seg.pt") # Model file, e.g., yolo26s.pt or yolo26m-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()Encuentra detalles adicionales sobre el método sweep_annotator en nuestra sección de referencia aquí.
Anotación de etiqueta adaptativa
A partir de Ultralytics v8.3.167, circle_label y text_label han sido reemplazados por una función unificada adaptive_label. Ahora puedes especificar el tipo de anotación usando el argumento shape:
- Rectángulo:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="rect") - Círculo:
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
Watch: In-Depth Guide to Text & Circle Annotations with Python Live Demos | Ultralytics Annotations 🚀
import cv2
from ultralytics import YOLO
from ultralytics.solutions.solutions import SolutionAnnotator
from ultralytics.utils.plotting import colors
model = YOLO("yolo26s.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)[0]
boxes = results.boxes.xyxy.cpu()
clss = results.boxes.cls.cpu().tolist()
for box, cls in zip(boxes, clss):
annotator.adaptive_label(box, label=names[int(cls)], color=colors(cls, True), shape="circle")
writer.write(im0)
cv2.imshow("Ultralytics circle annotation", im0)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
writer.release()
cap.release()
cv2.destroyAllWindows()Consulta la página de referencia de SolutionAnnotator para información adicional.
Varios
Perfilado de código
Comprueba la duración de la ejecución/procesamiento de código usando with o como un 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"Formatos compatibles con Ultralytics
¿Necesitas usar programáticamente los formatos de imagen o video compatibles en Ultralytics? Usa estas constantes si es necesario:
from ultralytics.data.utils import IMG_FORMATS, VID_FORMATS
print(IMG_FORMATS)
# {'avif', 'bmp', 'dng', 'heic', 'heif', 'jp2', 'jpeg', 'jpeg2000', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp'}
print(VID_FORMATS)
# {'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv', 'webm'}Hacer divisible
Calcula el número entero más cercano a x que sea divisible uniformemente por y.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8Preguntas frecuentes
¿Qué utilidades están incluidas 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. Las utilidades clave incluyen auto-anotación para etiquetar conjuntos de datos, convertir COCO a formato YOLO con convert_coco, compresión de imágenes y división automática de conjuntos de datos. Estas herramientas reducen el esfuerzo manual, garantizan la consistencia y mejoran la eficiencia en el procesamiento de datos.
¿Cómo puedo usar Ultralytics para auto-etiquetar mi conjunto de datos?
Si tienes un modelo de detección de objetos Ultralytics YOLO preentrenado, puedes usarlo con el modelo SAM para auto-anotar tu conjunto de datos en formato de segmentación. Aquí tienes un ejemplo:
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="path/to/new/data",
det_model="yolo26n.pt",
sam_model="mobile_sam.pt",
device="cuda",
output_dir="path/to/save_labels",
)For more details, check the auto_annotate reference section, or use Ultralytics Platform as a hosted, no-code alternative with click-based masking via SAM 2.1 or SAM 3, or predictions from pretrained and fine-tuned YOLO models for detect, segment, and OBB tasks.
¿Cómo convierto las anotaciones de un conjunto de datos COCO al formato YOLO en Ultralytics?
Para convertir anotaciones JSON de COCO al formato YOLO para detección de objetos, puedes usar la utilidad convert_coco. Aquí tienes un fragmento de código de muestra:
from ultralytics.data.converter import convert_coco
convert_coco(
"coco/annotations/",
use_segments=False,
use_keypoints=False,
cls91to80=True,
)For additional information, visit the convert_coco reference page.
¿Cómo puedo analizar la composición y distribución de mi conjunto de datos?
La plataforma Ultralytics proporciona analíticas automáticas del conjunto de datos: la pestaña Charts muestra la distribución de particiones, conteos de clases principales, histogramas de dimensiones de imagen y mapas de calor 2D de las posiciones de anotación, ayudándote a detectar desequilibrios y valores atípicos antes de entrenar.
¿Cómo puedo convertir cuadros delimitadores a segmentos en Ultralytics?
Para convertir datos de cuadros delimitadores existentes (en formato x y w h) a segmentos, puedes usar la función yolo_bbox2segment. Asegúrate de que tus 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",
)For more information, visit the yolo_bbox2segment reference page.