Ultralytics YOLO27: Iscriviti alla lista d'attesa.
Get Started
Lezioneintermedio

Etichettare e addestrare modelli di posa

Scrivi etichette dei keypoint con visibilità, imposta correttamente kpt_shape e flip_idx, addestra il modello su COCO8-pose e trasforma i keypoint in angoli articolari subordinati a una soglia di confidenza.

La stima della posa trasforma ogni persona in 17 punti numerati, dai quali si ricavano i valori che i prodotti offrono: angoli del gomito per l'ergonomia, angoli del ginocchio per la riabilitazione, altezza dell'anca per rilevare le cadute. Due chiavi del dataset determinano se puoi fidarti di quei punti; se sbagli anche una sola delle due, non ricevi errori: ottieni soltanto un modello che confonde destra e sinistra oppure si addestra silenziosamente senza la sua più economica forma di augmentation.

Esito

Addestra yolo26n-pose.pt su coco8-pose.yaml e calcola gli angoli dei gomiti sinistro e destro di ogni persona usando result.keypoints, ignorando le articolazioni per cui il modello non è abbastanza sicuro.

Percorso rapido
Se sai già come muoverti, ecco la versione breve.
  1. Riga di etichetta: classe, riquadro (4 valori), poi x y v per ogni keypoint, tutti normalizzati; v è 0 (non etichettato), 1 (occluso) oppure 2 (visibile).

  2. Imposta kpt_shape: [K, 3] e un flip_idx che scambi ogni coppia destra-sinistra.

  3. yolo pose train data=coco8-pose.yaml model=yolo26n-pose.pt epochs=1 imgsz=320.

  4. Leggi result.keypoints.xy e .conf; salta qualsiasi calcolo le cui articolazioni scendano sotto una soglia minima di confidenza.

Pratico

La riga di etichetta dei keypoint#

Stima della posa Ultralytics YOLO di tre corridori, ciascuno con un riquadro della persona e uno scheletro corporeo a 17 keypoint

Una riga di etichetta della posa è una riga di rilevamento a cui vengono aggiunti i keypoint. Ogni coordinata è normalizzata tra 0 e 1 e i keypoint compaiono nello stesso ordine fisso in ogni riga. Una vera riga di COCO8-pose, abbreviata dopo i primi quattro keypoint:

0 0.671279 0.617945 0.645759 0.726859 0.519751 0.381250 2.000000 0.550936 0.348438 2.000000 0.488565 0.367188 2.000000 0.642412 0.354687 2.000000 ...
ValoriSignificato
0indice della classe (persona)
0.671279 0.617945 0.645759 0.726859centro x, centro y, larghezza e altezza del riquadro
0.519751 0.381250 2keypoint 0 (naso): x, y, visibilità
…altri 16 keypoint con lo stesso schema: 5 + 17 × 3 = 56 valori per riga

Il flag di visibilità segue la convenzione COCO: 2 visibile, 1 etichettato ma occluso, 0 non etichettato. Ultralytics esclude dalla loss i keypoint con v = 0, così un polso mancante non insegna al modello a prevedere polsi in (0, 0).

Editor di annotazione Ultralytics Platform su un'immagine COCO8-pose, con scheletri a 17 keypoint disegnati sulle persone che tagliano una torta

Etichetta le articolazioni occluse che riesci a posizionare

Usa 1 per un'articolazione occlusa che riesci a posizionare con sicurezza — un'anca dietro un tavolo, un polso dietro la schiena; verrà comunque usata per l'addestramento. Riserva 0 alle articolazioni che nessuno potrebbe individuare. Assegnare 0 a ogni articolazione nascosta elimina proprio i casi difficili di cui il modello ha bisogno.

La guida ai dataset di posa descrive anche la variante a due valori (x y soltanto, kpt_shape: [K, 2]) per i dataset senza informazioni sulla visibilità.

kpt_shape e flip_idx#

Il file YAML del dataset aggiunge due chiavi ai consueti path, train, val e names:

kpt_shape: [17, 3] # 17 keypoints, each x, y, visibility
flip_idx: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]

Ordine dei 17 keypoint COCO su una persona in piedi, numerati da 0 per il naso a 16 per la caviglia destra

flip_idx indica all'augmentation con ribaltamento orizzontale quale keypoint corrisponde a ciascun keypoint nell'immagine speculare. Se ribalti una persona, il polso sinistro (9) finisce nel punto in cui si trovava il polso destro (10); quindi, la posizione 9 di flip_idx contiene 10 e la posizione 10 contiene 9, mentre il naso (0) corrisponde a sé stesso. Ogni augmentation sposta lo scheletro insieme ai pixel, ma il ribaltamento è l'unica che richiede anche la mappa degli indici:

Aumentazioni della posa di un corridore: originale, ribaltamento orizzontale, rotazione, scala, colore HSV e mosaico, con lo scheletro dei punti chiave che segue ogni trasformazione

Cosa succede quando flip_idx è errato, come verificato nel codice sorgente installato:

  • Assente: durante l'addestramento viene registrato un avviso e fliplr e flipud vengono impostati a 0, quindi perdi la tua aumentazione più economica.
  • Lunghezza errata: l'addestramento si interrompe con un ValueError che segnala la mancata corrispondenza: è l'unico errore esplicito.
  • Lunghezza corretta, coppie errate: non viene generato alcun avviso. Metà dei campioni ribaltati insegna al modello che sinistra è destra, e nelle immagini di validazione compaiono inversioni destra-sinistra nelle pose simmetriche.

Addestra su COCO8-pose#

Mosaico di addestramento COCO8-pose: persone in motocicletta, sotto un ombrello rosa, in uno skate park e a cavallo, ciascuna con un riquadro attorno alla persona e uno scheletro di punti chiave colorato

from ultralytics import YOLO

model = YOLO("yolo26n-pose.pt")
model.train(data="coco8-pose.yaml", epochs=1, imgsz=320, device="cpu")
metrics = model.val()
print(f"box  mAP50-95: {metrics.box.map:.3f}")
print(f"pose mAP50-95: {metrics.pose.map:.3f}")
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95)     Pose(P          R      mAP50  mAP50-95)
                   all          4         14          1      0.783      0.893      0.643      0.966      0.571      0.575      0.326
box  mAP50-95: 0.643
pose mAP50-95: 0.326

Come per la segmentazione, la tabella ha due sezioni. Box valuta i riquadri delle persone; Pose valuta il posizionamento dei punti chiave con la Similarità dei punti chiave degli oggetti (OKS), all'interno dello stesso meccanismo mAP. Pose mAP50-95 è il criterio di rilascio per un prodotto di stima della posa: la prossima lezione mostra come OKS stabilisce se un punto chiave è corretto.

Dai punti chiave agli angoli delle articolazioni#

result.keypoints contiene xy (N × K × 2, pixel), xyn (normalizzati) e conf (N × K), nell'ordine COCO mostrato sopra. L'angolo di un'articolazione è l'angolo tra i due vettori degli arti che si incontrano in quel punto: si calcola con un prodotto scalare:

import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-pose.pt")
result = model("https://ultralytics.com/images/bus.jpg")[0]
kpts = result.keypoints.cpu().numpy()  # people x 17 x (x, y, conf)

SHOULDER, ELBOW, WRIST = 5, 7, 9  # left arm, COCO keypoint order
for person, (xy, conf) in enumerate(zip(kpts.xy, kpts.conf)):
    if conf[[SHOULDER, ELBOW, WRIST]].min() < 0.5:
        print(f"person {person}: left arm not visible enough")
        continue
    a, b, c = xy[SHOULDER], xy[ELBOW], xy[WRIST]
    cos = np.dot(a - b, c - b) / (np.linalg.norm(a - b) * np.linalg.norm(c - b))
    print(f"person {person}: left elbow angle {np.degrees(np.arccos(cos)):.0f} deg")
person 0: left elbow angle 71 deg
person 1: left elbow angle 96 deg
person 2: left elbow angle 59 deg
person 3: left arm not visible enough
person 4: left arm not visible enough

Riga per riga: kpts.xy[p] è costituito dai 17 punti della persona p espressi in pixel; a - b e c - b sono i vettori del braccio e dell'avambraccio, con origine nel gomito; il loro prodotto scalare normalizzato è il coseno dell'angolo che li separa. Un braccio disteso indica un valore vicino a 180°, uno completamente piegato un valore vicino a 30°. Le persone 3 e 4 hanno almeno un'articolazione del braccio sinistro con confidenza inferiore a 0.5, quindi lo script non ne misura l'angolo.

Applica una soglia di confidenza a ogni articolazione

Sintomo: angoli apparentemente affidabili per persone con le braccia fuori dall'inquadratura. Causa: il modello restituisce una coordinata per ogni keypoint, che sia occluso o meno. Soluzione: salta qualsiasi calcolo le cui articolazioni non raggiungano una soglia minima di confidenza (0.5 in questo caso) e registra la frequenza con cui li salti: un aumento indica in anticipo un cambiamento della videocamera o dell'illuminazione.

Provalo

Esegui un'epoca di addestramento su coco8-pose.yaml e registra mAP50-95 di box e pose. Poi estendi pose.py per riportare anche l'angolo del gomito destro (punti chiave 6, 8, 10) ed elenca quali persone nell'immagine dell'autobus hanno entrambe le braccia misurabili.

Criteri di completamento
La lezione è completata quando tutte le seguenti condizioni sono soddisfatte.
  • L'addestramento è terminato e hai registrato mAP50-95 di box e pose.

  • Lo script stampa entrambi gli angoli dei gomiti per ogni persona, ignorando i bracci al di sotto della soglia di confidenza.

  • Sai spiegare cosa succede quando flip_idx è assente, ha una lunghezza errata o contiene coppie errate.

Mostra la soluzione
import numpy as np

from ultralytics import YOLO

ARMS = {"left": (5, 7, 9), "right": (6, 8, 10)}  # shoulder, elbow, wrist
kpts = YOLO("yolo26n-pose.pt")("https://ultralytics.com/images/bus.jpg")[0].keypoints.cpu().numpy()

for person, (xy, conf) in enumerate(zip(kpts.xy, kpts.conf)):
    for side, (s, e, w) in ARMS.items():
        if conf[[s, e, w]].min() < 0.5:
            continue
        a, b, c = xy[s], xy[e], xy[w]
        cos = np.dot(a - b, c - b) / (np.linalg.norm(a - b) * np.linalg.norm(c - b))
        print(f"person {person}: {side} elbow {np.degrees(np.arccos(cos)):.0f} deg")
person 0: left elbow 71 deg
person 0: right elbow 94 deg
person 1: left elbow 96 deg
person 2: left elbow 59 deg
person 2: right elbow 135 deg

Per le persone 0 e 2 è possibile misurare entrambe le braccia. Il braccio destro della persona 1 e entrambe le braccia delle persone 3 e 4 sono al di sotto della soglia di confidenza di 0.5, quindi lo script le ignora invece di fare supposizioni.

Se flip_idx è assente, l'aumentazione tramite ribaltamento viene disattivata con un avviso; una lunghezza errata interrompe l'addestramento con un ValueError; un flip_idx dall'aspetto valido ma con coppie errate addestra silenziosamente su etichette specchiate, causando inversioni destra-sinistra durante la validazione.

Prossimi passi

Nel prossimo passaggio progettiamo punti chiave per oggetti che non sono persone e impariamo come OKS stabilisce se un punto chiave è corretto.

Accedi per salvare i progressi