Link to this sectionUtilidades simples#
El paquete ultralytics ofrece una variedad de utilidades para respaldar, 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 herramientas de Ultralytics.
Watch: Ultralytics Utilities | Auto Annotation, Explorer API and Dataset Conversion
Link to this sectionDatos#
Link to this sectionEtiquetado automático / Anotaciones#
La anotación de datasets es un proceso que consume mucho tiempo y recursos. Si tienes un modelo de detección de objetos de Ultralytics YOLO entrenado con una cantidad razonable de datos, puedes usarlo con SAM para autoanotar 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 (bounding boxes) de detección de objetos.
Link to this sectionVisualizar anotaciones del dataset#
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 clase y ajusta el color del texto según la luminancia del fondo para una mejor 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,
)Link to this sectionConvertir máscaras de segmentación al formato YOLO#

Utiliza esto para convertir un dataset de imágenes de máscaras 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)Link to this sectionConvertir COCO al formato YOLO#
Utiliza esto para convertir anotaciones JSON de COCO al formato YOLO. Para datasets de detección de objetos (cuadros delimitadores), establece use_segments y use_keypoints como 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.
Link to this sectionObtener dimensiones de cuadros delimitadores#
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()}")Link to this sectionConvertir cuadros delimitadores a segmentos#
Con datos de cuadros delimitadores x y w h existentes, conviértelos a segmentos usando la función yolo_bbox2segment. Organiza 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.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.
Link to this sectionConvertir segmentos a cuadros delimitadores#
Si tienes un dataset que utiliza el formato de dataset de segmentación, puedes convertirlos fácilmente en cuadros delimitadores verticales (u 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.
Link to this sectionUtilidades#
Link to this sectionCompresión de imágenes#
Comprime un solo archivo de imagen a un tamaño reducido mientras conservas 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 cambiará su tamaño.
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)Link to this sectionDivisión automática de dataset#
Divide automáticamente un dataset en divisiones de train/val/test y guarda las divisiones resultantes 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 más detalles sobre esta función.
Link to this sectionPolígono de segmento a máscara binaria#
Convierte un solo polígono (como una lista) en una máscara binaria del tamaño de imagen especificado. El polígono debe ser un array 1D plano de N coordenadas que enumere valores x, y alternos que definan el contorno del polígono.
N debe ser siempre 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,
)Link to this sectionCuadros delimitadores (Bounding Boxes)#
Link to this sectionInstancias 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) se pueden acceder utilizando la clase Bboxes, pero si prefieres trabajar con las funciones directamente, consulta las siguientes subsecciones para saber cómo importarlas de forma independiente.
Link to this sectionEscalar cuadros#
Al escalar una imagen hacia arriba o hacia abajo, puedes escalar adecuadamente las coordenadas de los cuadros delimitadores correspondientes 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]]
# )Link to this sectionConversiones de formato de cuadros delimitadores#
Link to this sectionXYXY → XYWH#
Convierte las coordenadas del cuadro delimitador del formato (x1, y1, x2, y2) al formato (x, y, ancho, alto), 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]]
# )Link to this sectionTodas 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.
Link to this sectionGraficado#
Link to this sectionUtilidades de anotación#
Ultralytics incluye una clase Annotator para anotar varios tipos de datos. Se utiliza mejor con cuadros delimitadores de detección de objetos, puntos clave de pose y cuadros delimitadores orientados.
Link to this sectionAnotació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 obtener información adicional.
Link to this sectionAnotación de barrido (Sweep) 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í.
Link to this sectionAnotació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 más información.
Link to this sectionMiscelánea#
Link to this sectionPerfilado de código#
Comprueba la duración de ejecución/procesamiento del código, ya sea 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"Link to this sectionFormatos soportados por Ultralytics#
¿Necesitas utilizar programáticamente los formatos de imagen o vídeo soportados 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'}Link to this sectionHacer divisible#
Calcula el número entero más pequeño mayor o igual a x que es divisible uniformemente por y.
from ultralytics.utils.ops import make_divisible
make_divisible(7, 3)
# >>> 9
make_divisible(7, 2)
# >>> 8Link to this sectionFAQ#
Link to this section¿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 la autoanotación para etiquetar datasets, la conversión de COCO al formato YOLO con convert_coco, la compresión de imágenes y la división automática de datasets. Estas herramientas reducen el esfuerzo manual, garantizan la consistencia y mejoran la eficiencia del procesamiento de datos.
Link to this section¿Cómo puedo usar Ultralytics para autoetiquetar mi dataset?#
Si tienes un modelo de detección de objetos Ultralytics YOLO preentrenado, puedes usarlo con el modelo SAM para autoanotar tu dataset 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",
)Para más detalles, consulta la sección de referencia de auto_annotate, o usa la plataforma Ultralytics como una alternativa alojada sin código con enmascaramiento basado en clics a través de SAM 2.1 o SAM 3, o predicciones de modelos YOLO preentrenados y ajustados para tareas de detección, segmentación y OBB.
Link to this section¿Cómo convierto las anotaciones de un dataset 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,
)Para información adicional, visita la página de referencia de convert_coco.
Link to this section¿Cómo puedo analizar la composición y distribución de mi dataset?#
La plataforma Ultralytics proporciona análisis automáticos del dataset: la pestaña Charts muestra la distribución de las divisiones, los recuentos de las clases principales, histogramas de dimensiones de imagen y mapas de calor 2D de las posiciones de las anotaciones, lo que te ayuda a detectar desequilibrios y valores atípicos antes de entrenar.
Link to this section¿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",
)Para más información, visita la página de referencia de yolo_bbox2segment.