Puntos de pádel

Cómo funciona

Detectar el saque y el final de cada punto en video amateur, explicado paso a paso: qué técnica usamos, de qué paper sale y qué número la justifica.

El problema

Una cámara fija detrás de una de las paredes de fondo graba el partido entero. Queremos una lista de intervalos [saque, fin], uno por punto. Lo difícil no es el pádel sino el video amateur:

  • Ruido de otras canchas. Pelotazos, gritos y jugadores de las canchas vecinas aparecen en el audio y en la imagen.
  • Imagen pobre. Vidrios empañados o sucios, gran angular con distorsión, luz de galpón o de noche, jugadores cercanos que salen de cuadro.
  • Mucho tiempo muerto que se parece al juego. Juntar pelotas, peloteos entre puntos, pelotas quietas tiradas en la cancha.
  • Cada club es distinto. Altura de la cámara, colores, encuadre. Lo que se aprende en una cancha tiene que servir en otra.

Regla del proyecto: el marcador que aparece sobreimpreso en el video nunca entra al modelo. Lo leemos con OCR sólo para validar: cada cambio de marcador debería corresponder a exactamente un punto terminado.

Etiquetas: la verdad contra la que medimos

Tres partidos en tres clubes distintos (44, 33 y 39 minutos) se etiquetaron con un protocolo escrito: el punto empieza cuando la paleta del sacador toca la pelota en el primer saque y termina cuando la pelota muere. Una falta seguida de segundo saque es el mismo punto. Las etiquetas las hicieron agentes de IA revisando hojas de contacto a 1 y 4 cuadros por segundo, con el marcador tapado. En total: 275 puntos.

// labels_v2/lgl.json (extracto)
{ "start": 42.2, "end": 61.5, "conf": 0.85,
  "note": "saque del lado cercano; peloteo largo, terminó en la red" },
{ "start": 78.6, "end": 82.0, "conf": 0.90,
  "note": "saque del lado cercano; terminó con un smash ~81.5" }

Auditoría con una señal débil

El marcador no sirve para detectar, pero sí para sospechar: si entre dos cambios de marcador hay cero o dos puntos etiquetados, algo está mal. Esas ventanas se volvieron a revisar a mano, sin mostrar el marcador. Es la idea de confident learning (Northcutt et al., 2021): usar una señal ruidosa para encontrar errores de etiqueta, no para reemplazarlas.

PartidoAlertasConfirmadasCoincidencia con el marcador
Fecha 1 de liga9496 %
Set 3342186 %
Partido 1292290 %

El error más común era confundir un punto corto con «una falta y segundo saque». La regla que lo resolvió: si el saque siguiente viene de la otra mitad de la cancha, es un punto nuevo.

Jugadores en coordenadas de cancha

Es la señal que más pesa. Tres pasos:

  1. Pose. YOLO11-pose (Ultralytics, 2024; familia YOLO de Redmon et al., 2016) detecta personas y 17 puntos del cuerpo con el esquema de COCO (Lin et al., 2014), a 15 cuadros por segundo sobre la imagen en 1080p.
  2. Homografía. Una vez por cámara marcamos seis puntos del piso cuya posición real conocemos (la T de saque, el centro de la red, los extremos de la red y las esquinas del fondo). Con eso se estima una homografía, la transformación proyectiva que lleva el plano del piso en la imagen al plano de la cancha en metros (Hartley y Zisserman, 2004).
  3. Filtrar y describir. El pie de cada persona se proyecta a la cancha. Quien cae afuera, sea de una cancha vecina, del público o del pasillo, se descarta. Con los que quedan calculamos 34 números cada 0,2 s: cuántos hay en cada mitad, a qué distancia de la red, qué tan rápido se mueven, quién tiene el brazo arriba, quién está al fondo y quieto, y si hay un jugador al fondo de cada lado en diagonal, que es la formación típica del saque.
Cancha de noche con las líneas calibradas dibujadas en blanco; los cuatro jugadores marcados en azul y una persona de la cancha vecina marcada en gris.
Set 3, de noche. Las líneas blancas son la cancha reconstruida a partir de seis puntos. En azul, los jugadores que el modelo usa; en gris, la gente de la cancha vecina, que queda afuera. A la derecha, las mismas posiciones vistas desde arriba.
# court.py: seis puntos del piso -> homografía imagen -> metros
COURT = np.float32([(5, 3.05), (5, 10), (0, 10), (10, 10), (0, 20), (10, 20)])
H, _ = cv2.findHomography(np.float32(landmarks[match]), COURT)
pies_en_metros = cv2.perspectiveTransform(pies_en_pixeles, H)

Por qué importa: una grilla de movimiento en píxeles funciona muy bien dentro de un mismo partido, pero se rompe al cambiar de cámara. Las posiciones en metros significan lo mismo en cualquier club.

Audio: útil, pero engañoso

Cada golpe de pelota es un transitorio agudo. Lo medimos con spectral flux, el aumento de energía entre ventanas consecutivas del espectrograma entre 1,5 y 10 kHz, una técnica clásica de detección de onsets (Bello et al., 2005).

Dos minutos de la Fecha 1. Los picos son golpes; las franjas azules, los puntos etiquetados a mano. Hay golpes fuertes entre puntos, de las canchas vecinas y de los peloteos para devolver la pelota, y golpes débiles dentro de los puntos, contra el vidrio del fondo.

Sumar el audio a las señales de jugadores no mejoró el resultado entre clubes. Confirma la intuición inicial: el sonido solo no alcanza.

Embeddings de imagen

DINOv2 (Oquab et al., 2023) es un modelo de visión autosupervisado cuyos vectores describen bien una escena sin entrenarlo para nada en particular. Tomamos 5 cuadros por segundo, tapamos la zona del marcador y guardamos el vector global más una grilla de 3 × 4 zonas. Esos vectores se reducen a 96 números con PCA. Solos generalizan peor que los jugadores, pero ayudan a ubicar el final del punto: cuando todos dejan de jugar, la escena cambia de una forma que la pose no captura del todo.

Modelo temporal

El partido se corta en pasos de 0,2 s. Para cada paso el modelo produce tres probabilidades: en juego, empieza un punto acá y termina un punto acá. Es una red convolucional 1D con dilataciones crecientes (1, 2, 4, 8, 16, dos veces), la misma idea de WaveNet (van den Oord et al., 2016) y de las TCN (Bai, Kolter y Koltun, 2018), usada para segmentar acciones en video por MS-TCN (Farha y Gall, 2019). Cada salida ve unos 50 segundos de contexto, suficiente para entender «hubo un saque hace 20 segundos y todos siguen corriendo».

class Net(nn.Module):
    # 10 bloques residuales, kernel 5, dilaciones 1..16: ~50 s de contexto
    def __init__(s, d_in, h=64):
        s.inp = nn.Sequential(nn.Dropout(0.3), nn.Conv1d(d_in, h, 1))
        s.blocks = nn.ModuleList([nn.Sequential(
            nn.Conv1d(h, h, 5, padding=2 * d, dilation=d), nn.GELU(),
            nn.Dropout(0.1), nn.Conv1d(h, h, 1)) for d in (1, 2, 4, 8, 16) * 2])
        s.out = nn.Conv1d(h, 3, 1)          # en juego · inicio · fin

Detalles que importaron: cada partido se normaliza con su propia media y desvío, para que «rápido» signifique rápido para esa cámara; se entrena con AdamW (Loshchilov y Hutter, 2019) y un ciclo de learning rate (Smith y Topin, 2017); y el resultado final promedia 20 redes, 5 semillas por cada una de 4 combinaciones de señales. Un ensamble así es simple y estabiliza mucho (Lakshminarayanan et al., 2017).

Partido 1, minutos 25 a 28, predicho por modelos que nunca vieron ese club. En azul claro, la probabilidad de «en juego»; la línea fina, la probabilidad de inicio; la punteada, el umbral. Debajo, la etiqueta (negro) y la detección (azul). Las líneas naranjas son cambios de marcador, que llegan unos segundos después de cada punto.

De probabilidades a puntos

Cortar la curva en un umbral da intervalos, pero los peloteos largos, con globos y pausas, se parten en dos. La solución es una regla del deporte: todo punto empieza con un saque. Si dos intervalos están separados por menos de 6 segundos y al comienzo del segundo no hay un pico de «inicio», se unen.

Un peloteo largo de la Fecha 1. Arriba, el umbral solo lo parte en pedazos. Abajo, la regla del saque lo une y coincide con la etiqueta (barra negra).
# decode(): umbral 0,6 -> segmentos -> unir huecos sin saque -> afinar bordes
if hueco < 1.0 or (hueco < 6.0 and max(P_inicio[cerca_del_comienzo]) < 0.4):
    unir(anterior, segmento)
inicio = argmax(P_inicio[±2 s]);  fin = argmax(P_fin[±2 s])

Sólo esta regla subió el acierto medio de 0,84 a 0,87.

Evaluación honesta

Con pocos partidos es fácil engañarse. Tres reglas:

  • Dejar un club afuera. Cada partido se predice con modelos entrenados sólo con los otros dos. Es la pregunta real: ¿funciona en una cancha nueva? El cambio de distribución entre clubes es el problema central (Quiñonero-Candela et al., 2009).
  • Ajuste anidado. Los parámetros del decodificador también se eligen sin mirar el partido evaluado. Elegirlos mirando el resultado infla los números (Varma y Simon, 2006).
  • Coincidencia uno a uno. Un punto detectado cuenta si se superpone al menos un 30 % (IoU) con uno etiquetado, y cada etiqueta se usa una sola vez.
VersiónEntrenado conF1 en club nuevo
Movimiento y pose en píxeles + audio + imagen1 club0,58 – 0,65
Jugadores en metros1 club0,73 – 0,75
Jugadores en metros2 clubes0,84
+ regla del saque2 clubes0,87
+ ensamble con audio e imagen2 clubes0,89

Como contraste: la primera versión daba 0,92 evaluada dentro del mismo partido, y cayó a 0,6 en un club nuevo. Medir mal habría escondido el problema.

Resultado final por partido: F1 0,93, 0,91 y 0,89. El saque se ubica a menos de 1 segundo en el 70–82 % de los puntos; el final, en el 49–64 %.

¿Quién ganó el punto? Marcador automático

El paso siguiente es generar el marcador sin leerlo: decidir quién ganó cada punto y llevar la cuenta con las reglas. El marcador real se usa sólo para entrenar y medir, siempre dejando afuera el club que se evalúa.

1. Qué pareja está de cada lado

Cada jugador se reconoce por el color de su remera y su short, medidos sobre los puntos del cuerpo que da la pose. Agrupando esos colores salen cuatro identidades; las dos que aparecen juntas del mismo lado forman una pareja. Un modelo oculto de Markov suaviza la secuencia, porque los lados sólo cambian entre games.

Sorpresa amateur: el reglamento dice que se cambia de lado en los games impares. En la Fecha 1 se cumple exacto; en el Set 3 y en el Partido 1 las parejas no cambiaron de lado en todo el set. Por eso los lados salen de ver a los jugadores, no del reglamento.

2. Quién saca

La formación del saque (un jugador al fondo de cada lado, en diagonal, quietos y el sacador con el brazo abajo) se reconoce con un clasificador simple: acierta el lado del saque en el 91–100 % de los puntos de un club nuevo. El que saca gana el 60–65 % de los puntos.

3. Dónde muere la pelota

Un detector de objetos general (YOLO11 entrenado en COCO, clase «pelota») corre sobre cada cuadro a 30 fps. Las detecciones se unen en trayectorias con un modelo de velocidad constante; las pelotas quietas —tiradas en la cancha o en la mano del que espera para sacar— se descartan porque no se mueven. Cada vez que la pelota pasa de bajar a subir en la imagen hay un pique o un golpe bajo, y su posición en metros dice de qué lado fue.

Cuatro finales de punto con la trayectoria de la pelota dibujada en colores y cruces blancas en los piques.
Últimos segundos de cuatro puntos del Set 3. Los círculos son la pelota (de violeta a verde con el tiempo) y las cruces, los piques o golpes bajos detectados.

La física del juego aparece sola: si el último pique fue en tu lado, casi siempre perdiste (doble pique o pelota a la red). Siete señales bastan —lado del último pique, posición de los piques, de qué lado queda la pelota y quién estaba en la red— y rinden mejor que modelos con cientos de variables.

4. Las reglas como decodificador

Con punto de oro, un game termina cuando una pareja llega a su cuarto punto; el set, a 6 con dos de diferencia o con tie-break a 7. Un programa dinámico recorre todos los marcadores posibles y elige la secuencia de ganadores más probable que respete las reglas, el saque alternado por games y la ventaja del que saca. También admite un punto de más o de menos, por cortes del video o errores de detección.

Partido (club nuevo)Punto bien asignadoGame bien asignado
Fecha 1 de liga64 %69 %
Set 374 %82 %
Partido 175 %67 %

Con los límites de los puntos marcados a mano; todo automático, el acierto por punto es 62–76 %. El primer set del Partido 1 sale exacto (6–3). Pero el marcador se arrastra: en la Fecha 1, un solo game mal asignado al principio desplaza todo lo que sigue. Para llegar a un marcador confiable falta un detector de pelota entrenado para pádel (los generales confunden raquetas fluorescentes y remeras) y más partidos etiquetados.

Lo que no funcionó

La pelota, buscada por color

La intuición era buena: el pique y el golpe de la pelota definen el punto. Buscamos manchas amarillo-verdosas que se mueven entre tres cuadros, sacamos las líneas y las pelotas quietas con un fondo mediano, descartamos lo que cae sobre una persona y unimos detecciones en trayectorias cortas.

Mapa de calor de detecciones de pelota: se concentran sobre la remera amarilla de un jugador y sobre el césped verde alrededor de la cancha.
Partido 1: dónde encontró «pelotas» el detector por color. Se concentran en una remera amarilla y en el césped sintético verde.

Por sí sola, esta señal separa juego de pausa apenas mejor que el azar (AUC 0,60–0,68) y al sumarla al modelo empeoró un poco. Hace falta un detector entrenado, como TrackNet (Huang et al., 2019).

Señales atadas a la cámara

Grillas de movimiento y de pose en píxeles aprenden la cancha, no el juego: rinden muy bien en el partido donde se entrenan y mal en otro club.

Qué sigue

  • Un detector de pelota entrenado para pádel (estilo TrackNet): afinaría el final de cada punto y, sobre todo, quién lo ganó.
  • Más clubes: cada club nuevo en el entrenamiento mejoró bastante el resultado en los demás.
  • Reconocer mejor el saque del lado lejano, donde está la mayoría de los puntos cortos perdidos.
  • Corregir la distorsión del lente en la calibración: cerca de la cámara el error es de 0,5 a 1 metro.

Referencias

  1. Redmon, Divvala, Girshick y Farhadi. You Only Look Once: Unified, Real-Time Object Detection. CVPR 2016.El origen de la familia YOLO que usamos para detectar jugadores.
  2. Ultralytics. YOLO11, 2024.El modelo de pose concreto (yolo11m-pose).
  3. Lin et al. Microsoft COCO: Common Objects in Context. ECCV 2014.Define los 17 puntos del cuerpo (hombros, muñecas, caderas…) que usamos para brazos arriba o saque de abajo.
  4. Hartley y Zisserman. Multiple View Geometry in Computer Vision, 2.ª ed. Cambridge University Press, 2004.Homografías: cómo pasar del plano del piso en la imagen a metros reales.
  5. Bello et al. A Tutorial on Onset Detection in Music Signals. IEEE Trans. Speech and Audio Processing, 2005.Spectral flux para detectar golpes en el audio.
  6. Oquab et al. DINOv2: Learning Robust Visual Features without Supervision. 2023.Los embeddings de imagen.
  7. van den Oord et al. WaveNet: A Generative Model for Raw Audio. 2016.Convoluciones dilatadas para ver mucho contexto con pocas capas.
  8. Bai, Kolter y Koltun. An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling. 2018.Por qué una TCN simple compite con las redes recurrentes en secuencias.
  9. Farha y Gall. MS-TCN: Multi-Stage Temporal Convolutional Network for Action Segmentation. CVPR 2019.Segmentar un video largo en acciones cuadro a cuadro, el mismo tipo de problema.
  10. Lakshminarayanan, Pritzel y Blundell. Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles. NeurIPS 2017.Promediar varias redes entrenadas con distinta semilla.
  11. Loshchilov y Hutter. Decoupled Weight Decay Regularization (AdamW). ICLR 2019.El optimizador.
  12. Smith y Topin. Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates. 2017.El ciclo de learning rate (one-cycle).
  13. Varma y Simon. Bias in error estimation when using cross-validation for model selection. BMC Bioinformatics, 2006.Por qué el ajuste del decodificador es anidado.
  14. Quiñonero-Candela, Sugiyama, Schwaighofer y Lawrence (eds.). Dataset Shift in Machine Learning. MIT Press, 2009.El marco para «funciona en un club, falla en otro».
  15. Northcutt, Jiang y Chuang. Confident Learning: Estimating Uncertainty in Dataset Labels. JAIR, 2021.Usar una señal ruidosa, el marcador en este caso, para encontrar etiquetas equivocadas.
  16. Huang et al. TrackNet: A Deep Learning Network for Tracking High-speed and Tiny Objects in Sports Applications. 2019.El camino para detectar bien la pelota.