Detección de objetos pequeños mediante el teselado de imágenes con Ultralytics YOLO, de Python a Rust
Descubre cuándo el teselado de imágenes ayuda a YOLO a detectar objetos pequeños, compara sus costes y ejecuta inferencia con teselas integrada en Python o Rust sin SAHI.
Onuralp Sezer17 min de lectura
¿Por qué un detector que funciona bien con fotos normales no detecta a la mayoría de las personas en una imagen tomada con un dron? A menudo, porque nunca las ve a tamaño real. Con el valor predeterminado imgsz=640, Ultralytics YOLO reduce tres veces una imagen de 1920 x 1080 antes de que el modelo la analice, por lo que un peatón de 15 píxeles de alto acaba midiendo unos 5 píxeles.
El teselado de imágenes puede conservar ese detalle de los objetos pequeños al ejecutar el modelo en ventanas solapadas de la imagen a resolución completa y combinar los resultados. En una imagen de VisDrone de nuestra documentación, permitió a Ultralytics YOLO26s pasar de 35 detecciones a 161. El coste es más trabajo por imagen: ocho entradas de tesela en lugar de una imagen.
El teselado ya está integrado en ambos extremos del despliegue. El paquete de Python tiene un argumento tile desde el 6 de noviembre, con Ultralytics 8.4.204, y el crate de Rust añadió una opción --tile el 9 de noviembre, con Ultralytics Inference 0.0.57. Esta guía explica cuándo el teselado recupera objetos pequeños, cuánto cuesta y cómo ejecutarlo en cada entorno.
El redimensionamiento es lo que oculta los objetos pequeños#
La detección de objetos pequeños es difícil por una razón sencilla: un objeto solo tiene los píxeles que tiene. Un modelo de detección de objetos aprende formas a partir de un puñado de píxeles por objeto y, cuando se reduce todo el fotograma para que su lado más largo mida 640 píxeles, las personas, los vehículos y los defectos lejanos quedan por debajo de lo que la red puede distinguir de la textura y el ruido.
Esto se aprecia sobre todo en las imágenes aéreas, el análisis de imágenes satelitales, las cámaras de tráfico y seguridad de gran angular y las fotos de inspección de alta resolución. VisDrone es un benchmark aéreo público muy utilizado: su documentación describe objetos que a menudo ocupan solo unas pocas decenas de píxeles en la imagen y aparecen en grupos densos con muchas oclusiones.
El teselado conserva esos píxeles. Con tile ajustado al tamaño de entrada del modelo, este ve varias ventanas a resolución nativa en lugar de procesar una sola vez el fotograma reducido. La idea es la que el artículo de SAHI denomina inferencia de hiperresolución asistida por recortes, que sus autores evaluaron con los conjuntos de datos aéreos VisDrone y xView.
En la guía de teselado de alta resolución, YOLO26s devuelve, con el umbral de confianza predeterminado y en un fotograma de VisDrone de 1920 x 1080, 35 detecciones en la imagen completa con imgsz=640 y 161 con tile=640, incluidos peatones, ciclistas y coches lejanos. La guía muestra ambas imágenes una al lado de la otra. Son recuentos de predicciones, no una evaluación con métricas. Ambos recuentos se obtuvieron con los mismos pesos; el teselado también cambió el contexto que veía cada ventana.

Un segundo fotograma de validación de VisDrone de 1920 x 1080: YOLO26s con la confianza predeterminada devuelve 8 detecciones en el fotograma completo con imgsz=640 y 128 con tile=640. Se muestra un recorte de la carretera, con cajas sin etiquetas de clase.
El teselado añade una entrada al modelo por cada ventana#
La guía define con precisión el uso de ventanas. Las ventanas se solapan un 20 % de base, y la última fila y columna se alinean con el borde de la imagen, por lo que las ventanas de los bordes pueden solaparse más. Si la imagen es más pequeña que la ventana, se utiliza una sola ventana que abarca toda la imagen.
Así es fácil calcular el coste. Un fotograma de 1920 x 1080 con tile=640 se procesa en ocho ventanas: cuatro en horizontal y dos en vertical. Un fotograma de 3840 x 2160 con tile=1280 también se procesa en ocho. Al aplicar la misma regla de solapamiento del 20 % a un fotograma de 3840 x 2160 con tile=640, se obtienen ocho columnas y cuatro filas, es decir, 32 ventanas. Por tanto, reducir a la mitad el tamaño de las ventanas en un fotograma 4K cuadruplica las entradas de tesela.

Las ocho ventanas que tile=640 utiliza en un fotograma de 1920 x 1080: las columnas empiezan en x = 0, 512, 1024 y 1280, y las filas en y = 0 y 440. Las franjas sombreadas aparecen en más de una ventana.
El procesamiento por lotes cambia la forma en que esas entradas llegan al modelo. En Python, batch establece cuántas ventanas se procesan juntas en una llamada de inferencia, y el crate de Rust hace lo mismo con --batch en una exportación con lote dinámico. El procesamiento por lotes puede mejorar el rendimiento, pero mide la latencia en tu hardware; nuestra guía sobre inferencias por lotes con Ultralytics YOLO explica por qué.
Así se compara el teselado con otras formas de dar más píxeles a los objetos pequeños:
| Enfoque | Entradas del modelo para un fotograma de 1920 x 1080 | Qué ve el modelo | Ideal cuando |
|---|---|---|---|
Imagen completa, imgsz=640 | 1 | Fotograma reducido 3 veces | Los objetos siguen siendo claramente visibles tras el redimensionamiento |
Imagen completa, imgsz=1280 | 1, con aproximadamente 4 veces el coste de cálculo de 640 | Fotograma reducido 1,5 veces | La memoria y la latencia permiten una entrada mayor |
tile=True con imgsz=640 | 8 | Ventanas de 640 píxeles a resolución nativa | Imágenes varias veces más grandes que la entrada del modelo |
tile=400 con imgsz=640 | Más de 8 | Ventanas ampliadas a 640 | Los objetos solo miden unos pocos píxeles de ancho, incluso a resolución nativa |
Cada tesela es una entrada de tamaño normal para el modelo, así que el teselado permite procesar imágenes muy grandes sin aumentar imgsz. Las salidas del tamaño de la imagen de origen, como las máscaras y los mapas de profundidad, siguen necesitando memoria proporcional a la imagen original, y max_det limita el número de máscaras de instancias que se conservan.
Cuándo ayuda el teselado y cuándo perjudica#
El teselado ayuda cuando los objetos son pequeños respecto al fotograma y este es mucho más grande que la entrada del modelo. Es adecuado para imágenes de drones y satélites, tráfico visto desde arriba, multitudes, estanterías de tiendas fotografiadas desde lejos e imágenes de inspección visual de placas o paneles completos.
Perjudica cuando los objetos son grandes. Una ventana solo ve parte de un camión que ocupa la mitad del fotograma, y la guía lo deja claro: los objetos más grandes que el solapamiento pueden seguir dividiéndose porque ninguna ventana los ve completos, y la combinación no une los fragmentos separados. También elimina el contexto global, que es más importante para la clasificación y la profundidad, ya que las salidas de las teselas pueden no coincidir en toda la imagen.
Las ventanas más pequeñas conllevan una desventaja más. Ampliar una ventana de 400 píxeles a 640 ayuda con objetos de solo unos pocos píxeles de ancho, pero también amplía el desorden del fondo, lo que puede producir falsos positivos. Compara dos o tres tamaños de tesela con tu propio conjunto de validación y presta atención tanto a la precisión como a la exhaustividad.
Cómo se combinan las teselas en un único resultado#
Cada ventana genera sus propias predicciones en coordenadas de ventana. El teselado las transforma a las coordenadas de la imagen de origen y devuelve un objeto Results por cada imagen original, de modo que el código posterior que lee result.boxes sigue funcionando sin cambios.
El solapamiento puede hacer que un objeto cercano a una unión se detecte dos veces. Para la detección, las duplicaciones se eliminan mediante la supresión no máxima con los ajustes iou, agnostic_nms y max_det; por tanto, nuestra guía para ajustar el umbral IoU de NMS se aplica directamente a las salidas teseladas. Si una ventana corta una caja, esta se descarta cuando otra ventana ve el objeto sin cortes en los bordes y una caja conservada lo cubre, de modo que en la unión se conserva la predicción más completa. Si una caja cortada no tiene otra coincidencia mejor, se conserva.

Ilustración del tratamiento de una unión en y = 640 en el mismo fotograma. Las cajas cian quedan cortadas por el borde inferior de las ventanas de la fila superior; las magenta proceden de las ventanas de la fila inferior. El panel derecho muestra la caja más completa que se conserva para cada coche tras la combinación.
Cada tarea de Ultralytics YOLO combina los resultados a su manera:
- Detect, segment, pose y OBB restauran las cajas, máscaras, puntos clave o cajas rotadas a las coordenadas de origen y aplican la selección de cajas; para OBB utilizan NMS rotada.
- La segmentación semántica une los mapas de clases y, cuando se solapan las ventanas, elige la tesela más centrada.
- La profundidad combina los mapas de profundidad solapados con pesos que aumentan hacia el centro de cada tesela.
- La clasificación calcula la media de las probabilidades de las teselas.
El flujo de predicción de Python también aplica teselado a las predicciones de YOLO-World, YOLOE, RT-DETR y FastSAM. SAM mantiene su propio flujo de recortes y no acepta tile.
Inferencia con teselas en Python mediante el argumento tile#
El teselado requiere Ultralytics 8.4.204 o posterior y no necesita paquetes adicionales. En el modo de predicción, pasa tile=True para usar imgsz como tamaño de ventana, o un número entero para especificar el tamaño de ventana por separado:
from ultralytics import YOLO
model = YOLO("yolo26s.pt")
# Referencia: una pasada sobre el fotograma reducido a 640 píxeles
full = model.predict("intersection.jpg", imgsz=640)
# Teselado: ventanas de 640 píxeles a resolución nativa, 8 ventanas por lote
tiled = model.predict("intersection.jpg", imgsz=640, tile=640, batch=8)
print(len(full[0].boxes), len(tiled[0].boxes))El mismo argumento funciona desde la CLI con yolo predict model=yolo26s.pt source=large-image.tif tile=640 imgsz=640 batch=8. Para vídeo, pasa stream=True para limitar el uso de memoria. En el modo de seguimiento, el rastreador se ejecuta una vez por fotograma sobre las predicciones combinadas.
El teselado no sirve solo para la predicción. Si tus imágenes son mucho más grandes que imgsz, entrena y valida con el mismo ajuste:
- Entrena con teselas mediante
model.train(data="aerial.yaml", tile=True, imgsz=640). Las etiquetas se recortan en cada ventana, se eliminan las instancias a las que les queda menos del 10 % del área de su caja original y las ventanas vacías se conservan como ejemplos negativos. - Valida con los resultados combinados mediante
model.val(data="aerial.yaml", tile=True, imgsz=640). Las predicciones se combinan antes de puntuarlas frente a las anotaciones originales, de modo que mAP refleja lo que desplegarás. - Guarda en caché las imágenes de origen grandes con
cache="ram", ya que el entrenamiento mezcla las teselas y, de lo contrario, tendría que decodificar varias veces la misma imagen grande. - Compara con una referencia de imagen completa usando la misma partición de validación antes de quedarte con el modelo teselado. Para conocer más formas de mejorar las puntuaciones con objetos diminutos, consulta nuestra lista de comprobación de mAP para objetos pequeños.
El entrenamiento con teselas muestra al modelo los objetos a la escala a la que los verá durante la predicción teselada. Nuestra guía de conjuntos de datos para detección con drones recorre todo el proceso de entrenamiento, teselado y evaluación con fotogramas 4K.
Los modelos exportados también admiten teselado. El teselado se ejecuta en el flujo de predicción de Python, por lo que un modelo exportado a ONNX o TensorRT mantiene su grafo de entrada normal, y YOLO("yolo26s.onnx").predict(source, tile=640) funciona como de costumbre, incluidos los tamaños de lote fijos de la exportación y el último lote parcial.

El conjunto de datos VisDrone en Ultralytics Platform, un benchmark listo para usar con el que probar tamaños de tesela antes de etiquetar tus propios datos.
Para probar primero los tamaños de tesela con datos públicos, empieza con el conjunto de datos VisDrone en Ultralytics Platform. Para hacer un seguimiento de una ejecución teselada junto a tu referencia, copia el comando de entrenamiento local del cuadro de diálogo de entrenamiento de Platform, establece project en el proyecto de Platform de tu referencia y añade tile=True para enviar allí las métricas de la ejecución teselada.
Inferencia con teselas en Rust mediante la nueva opción --tile#
Ultralytics Inference es nuestro crate de Rust y nuestra CLI para ejecutar modelos ONNX exportados mediante ONNX Runtime y modelos OpenVINO IR de forma nativa, sin un entorno de ejecución de Python durante la inferencia. Está pensado para servidores, contenedores y dispositivos edge con CPU, CUDA, TensorRT, CoreML, OpenVINO y otros proveedores de ejecución. La versión 0.0.57 incorpora el mismo enfoque de teselado que Python: un solapamiento de ventanas del 20 % de base, resultados transformados de vuelta a la imagen de origen y duplicados eliminados por clase.

Imagen ilustrativa. Una cámara al borde de la carretera con un ordenador edge, el tipo de despliegue sin Python al que está destinado el crate de Rust.
El equipo comprobó las salidas teseladas frente a Ultralytics Python en ONNX Runtime CPU, OpenVINO CPU, GPU y NPU, CUDA y TensorRT, con imágenes, vídeo y webcam. Se admiten modelos de detección, segmentación, segmentación semántica, profundidad, clasificación, pose y OBB.
Desde la CLI, añade --tile con un tamaño de ventana o pásalo sin valor para usar --imgsz. Exportar el modelo es un paso único en Python; la inferencia solo necesita el binario de Rust:
# One-time export in Python: a dynamic-batch ONNX model so several windows run per call
pip install -U "ultralytics[export-base]>=8.4.204"
yolo export model=yolo26s.pt format=onnx dynamic=True
# Install the Rust CLI
cargo install ultralytics-inference
# Tiled inference on a large image: 640-pixel windows, 8 per batch
ultralytics-inference predict --model yolo26s.onnx --source aerial.jpg --tile 640 --batch 8Como biblioteca, configura el teselado una vez en InferenceConfig y todas las llamadas a predict se ejecutarán con teselas. with_tile(0) utiliza el tamaño de inferencia:
use ultralytics_inference::{InferenceConfig, YOLOModel};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = InferenceConfig::new().with_tile(640);
let mut model = YOLOModel::load_with_config("yolo26s.onnx", config)?;
let results = model.predict("aerial.jpg")?;
if let Some(ref boxes) = results[0].boxes {
println!("{} detections", boxes.len());
}
Ok(())
}Las cajas duplicadas entre ventanas se eliminan mediante NMS por clase con --iou, cuyo valor predeterminado es 0.5 desde esa misma versión, en consonancia con los valores predeterminados de predicción de Ultralytics. El teselado está desactivado de forma predeterminada, porque cada ventana añade otra entrada al modelo. Actívalo cuando el detalle sea importante, mide la latencia de inferencia en el dispositivo de destino y elige el proveedor de ejecución adecuado; nuestra comparativa entre ONNX y TensorRT es útil para el hardware NVIDIA, y la guía de NVIDIA Jetson explica la configuración en el dispositivo.
Los usuarios de SAHI pueden cambiar al argumento de teselado integrado#
Si ya recortas imágenes con la biblioteca SAHI, el argumento integrado hace lo mismo dentro de Ultralytics, sin un segundo paquete ni un formato de resultados distinto. Nuestra guía de integración de SAHI está obsoleta; ahora se recomienda usar tile.
Para migrar un script de SAHI, basta sobre todo con cambiar los argumentos:
| SAHI | Teselado integrado |
|---|---|
AutoDetectionModel.from_pretrained(model_type="ultralytics", ...) | YOLO("yolo26s.pt") |
get_sliced_prediction(image, model, slice_height=256, slice_width=256, ...) | model.predict(image, tile=256) |
overlap_height_ratio, overlap_width_ratio | Solapamiento fijo de base del 20 %; ventanas de los bordes alineadas con el límite de la imagen |
PredictionResult de SAHI | Results estándar de Ultralytics |
Las ventanas son cuadradas, y el solapamiento y la combinación siguen las reglas descritas arriba en lugar del posprocesamiento configurable de SAHI, así que los resultados serán parecidos, pero no idénticos. Vuelve a comprobar los umbrales con un conjunto de validación después de cambiar.
La diferencia práctica está en la integración. tile se integra en el entrenamiento, la validación, la predicción y el seguimiento de Ultralytics con el mismo argumento, devuelve objetos Results estándar y ofrece una opción equivalente en el crate de Rust. Así, un tamaño de tesela que hayas validado en un notebook se puede trasladar a un binario de Rust en el dispositivo edge.
Quién debería activar el teselado#
Activa el teselado si ejecutas Ultralytics YOLO con imágenes varias veces más grandes que la entrada del modelo y la validación muestra que se pierden objetos pequeños: equipos que trabajan con drones y satélites, integradores de sistemas de tráfico y seguridad con cámaras de gran angular y equipos de inspección que fotografían placas, paneles o estanterías completas. Los usuarios de Rust disponen del mismo enfoque de teselado en hardware edge, sin un entorno de ejecución de Python.
Déjalo desactivado cuando los objetos sean grandes respecto al fotograma, cuando un imgsz más grande ya los recupere en una sola pasada o cuando el presupuesto de latencia no permita procesar varias entradas de tesela por fotograma. En todos los casos, compara los resultados teselados y los de la imagen completa en la misma partición de validación y con el mismo umbral de confianza, prestando atención a la exhaustividad, los falsos positivos y la latencia; conserva el teselado solo cuando la mejora compense el trabajo adicional.
Ultralytics Platform reúne esa comparación en un solo lugar: etiqueta tus propias imágenes de alta resolución o empieza con VisDrone, entrena una referencia con la imagen completa en GPU en la nube, entrena otra referencia con un imgsz más grande y registra una ejecución teselada desde tu propio equipo en el mismo proyecto. La guía de teselado de alta resolución detalla las opciones de teselado, y la documentación de Ultralytics Inference explica el despliegue con Rust.
Tanto el paquete de Python como el crate de Rust están disponibles bajo AGPL-3.0. Si vas a incorporar la detección teselada a un producto de código cerrado o a un dispositivo edge que enviarás a tus clientes, una licencia empresarial de Ultralytics permite el uso comercial del software de Ultralytics incluido sin las obligaciones de divulgar el código fuente de AGPL-3.0, sujeto a sus condiciones.
Preguntas frecuentes
El teselado de imágenes divide una imagen grande en ventanas solapadas, ejecuta el detector en cada ventana y combina las cajas de nuevo en la imagen original. Cuando la ventana coincide con el tamaño de entrada del modelo, los objetos pequeños conservan píxeles que perderían si se redimensionara toda la imagen. En Ultralytics YOLO, el argumento
tilelo hace con un solapamiento de base del 20 % y devuelve un resultado por imagen.Primero, comprueba si el problema es el redimensionamiento: si los objetos se reducen a unos pocos píxeles con
imgsz=640, prueba con unimgszotile=Truemás grande. Entrena con el mismo ajuste que usarás para predecir, para que el modelo aprenda los objetos a la escala de despliegue, y valida por tamaño y clase. El teselado es adecuado para imágenes varias veces más grandes que la entrada del modelo.Añade una entrada al modelo por ventana: un fotograma de 1920 x 1080 con
tile=640genera ocho entradas de tesela en lugar de una imagen. Ejecutar varias teselas en una sola llamada por lotes, conbatchen Python o--batchcon una exportación de lote dinámico en Rust, puede mejorar el rendimiento. Mide la latencia en el hardware de destino.No. Desde Ultralytics 8.4.204, el argumento integrado
tilepermite realizar inferencia por recortes sin paquetes adicionales y también aplica teselado al entrenamiento, la validación y el seguimiento. La guía de SAHI de nuestra documentación está obsoleta; ahora se recomienda usartile.Sí. En Python, los modelos exportados conservan su grafo de entrada normal y se pasa
tileapredictcomo de costumbre. En Rust, Ultralytics Inference 0.0.57 añade--tilea la CLI ywith_tileaInferenceConfig; el funcionamiento se comprobó frente a Python con ONNX Runtime CPU, OpenVINO, CUDA y TensorRT.Empieza con
tile=True, que utilizaimgszcomo tamaño de ventana. Usa una ventana más pequeña, comotile=400conimgsz=640, cuando los objetos solo midan unos pocos píxeles incluso a resolución nativa, y una más grande cuando exista el riesgo de que los objetos queden recortados en las uniones. Compara varios tamaños en tu conjunto de validación y presta atención tanto a la exhaustividad como a los falsos positivos.
Escrito por
Comentarios
Haz una pregunta, comparte tus resultados o ayuda a otra persona.










