Stima della posa e OBB
Leggi i keypoint e i riquadri ruotati da YOLO26, definisci una regola basata su ciascuno e riconosci quando il segnale determinante è la postura o l’angolo.
Una casa di riposo deve sapere quando qualcuno è caduto; un porto deve contare le navi affiancate in un’immagine ripresa da un drone. I riquadri standard non funzionano in nessuno dei due casi: un riquadro non indica se una persona è in piedi e un riquadro verticale attorno a una nave diagonale contiene perlopiù acqua. La stima della posa e gli OBB sono pensati proprio per questi due problemi.
Pratico
Pose: quando il segnale è la postura#

Un modello di stima della posa restituisce un riquadro per ogni persona e un elenco fisso di keypoint. I modelli addestrati su COCO-Pose prevedono 17 keypoint per persona — naso, occhi, orecchie, spalle, gomiti, polsi, anche, ginocchia e caviglie — sempre nello stesso ordine: l’indice 0 è il naso, l’11 l’anca sinistra e il 15 la caviglia sinistra. Ogni keypoint ha anche un valore di confidenza.
La regola utile più semplice: un corpo in piedi è più alto che largo; un corpo disteso sul pavimento è più largo che alto. Ecco il risultato sull’immagine dell’autobus, usando solo i keypoint di cui il modello è sicuro:
from ultralytics import YOLO
model = YOLO("yolo26n-pose.pt")
result = model("https://ultralytics.com/images/bus.jpg", verbose=False)[0]
for xy, conf in zip(result.keypoints.xy, result.keypoints.conf):
visible = xy[conf > 0.5] # drop keypoints the model couldn't see
width = float(visible[:, 0].max() - visible[:, 0].min())
height = float(visible[:, 1].max() - visible[:, 1].min())
posture = "unknown" if len(visible) < 5 else "lying" if width > height else "upright"
print(f"{len(visible):2d}/17 keypoints visible, body {width:3.0f} px wide x {height:3.0f} px tall -> {posture}")16/17 keypoints visible, body 117 px wide x 427 px tall -> upright
6/17 keypoints visible, body 80 px wide x 359 px tall -> upright
16/17 keypoints visible, body 91 px wide x 384 px tall -> upright
1/17 keypoints visible, body 0 px wide x 0 px tall -> unknown
2/17 keypoints visible, body 3 px wide x 6 px tall -> unknownTre persone sono chiaramente in piedi. Le ultime due righe corrispondono alla persona tagliata sul bordo sinistro e a un duplicato con bassa confidenza: con uno o due keypoint visibili non c’è abbastanza per giudicare, quindi la regola restituisce «sconosciuto» invece di tirare a indovinare. Un rilevatore di cadute pronto per la produzione aggiunge la dimensione temporale — la persona deve restare distesa per più di qualche secondo, dopo una caduta rapida — tramite il tracciamento.
Sintomo: scheletri con i polsi sospesi nel vuoto e regole sulla postura che si attivano con persone visibili solo in parte. Causa: keypoints.xy restituisce una posizione per tutti e 17 i keypoint, compresi quelli che il modello non è riuscito a vedere. Soluzione: filtra con keypoints.conf, come sopra, e richiedi un numero minimo di keypoint visibili prima di prendere una decisione.
La stima della posa è utile quando la risposta dipende da ciò che fa il corpo: cadute o sollevamenti con la schiena piegata per la sicurezza, angoli delle articolazioni e conteggio delle ripetizioni nello sport, come nel monitoraggio degli allenamenti, oppure postura del bestiame e punti di riferimento fissi su componenti con una disposizione personalizzata dei keypoint. Per rispondere a «c’è una persona qui?», usa il rilevamento standard.
OBB: quando l’angolo conta#

I lati di un riquadro standard sono paralleli all’immagine. Un riquadro di delimitazione orientato aggiunge una rotazione, rappresentata da centro, larghezza, altezza e angolo (xywhr). Nelle immagini dall’alto — satellitari, riprese da droni o con telecamere sopra i nastri trasportatori — gli oggetti sono orientati in ogni direzione e un riquadro verticale intorno a un oggetto diagonale contiene perlopiù sfondo, come accadrebbe con gli yacht qui sopra. Misura la differenza su una ripresa con drone di un porto turistico:
from ultralytics import YOLO
model = YOLO("yolo26n-obb.pt")
result = model("https://ultralytics.com/images/boats.jpg", verbose=False)[0]
obb = result.obb
rotated_area = obb.xywhr[:, 2] * obb.xywhr[:, 3] # width x height of each rotated box
x1, y1, x2, y2 = obb.xyxy.T # the axis-aligned box that would enclose the same object
upright_area = (x2 - x1) * (y2 - y1)
print(f"{len(obb)} objects, classes: {sorted({result.names[int(c)] for c in obb.cls})}")
cx, cy, w, h, angle = obb.xywhr[0].tolist()
print(f"first box: center=({cx:.0f}, {cy:.0f}) size={w:.0f}x{h:.0f} angle={angle:.2f} rad")
ratio = float((upright_area / rotated_area).median())
print(f"an axis-aligned box would be {ratio:.1f}x larger (median)")173 objects, classes: ['harbor', 'ship']
first box: center=(619, 850) size=33x108 angle=-0.25 rad
an axis-aligned box would be 2.1x larger (median)Un riquadro verticale copre circa il doppio dell’area rispetto al riquadro ruotato attorno alla stessa barca, e l’area in più è acqua. Questo causa due problemi: NMS rileva la sovrapposizione tra i riquadri verticali delle barche vicine e potrebbe eliminare rilevamenti corretti; inoltre, qualsiasi stima delle dimensioni risulta sovrastimata. I modelli OBB addestrati su dataset aerei come DOTA gestiscono direttamente queste scene. Nota che l’angolo è espresso in radianti: -0.25 rad corrisponde a circa -14°.
Scegliere tra rilevamento, stima della posa e OBB#
| Scenario | Attività più adatta | Perché |
|---|---|---|
| Contare le persone su un marciapiede | Rilevamento | La risposta è la presenza e la posizione |
| Rilevare una caduta in una casa di riposo | Stima della posa | Il segnale è l’orientamento del corpo |
| Contare gli squat in palestra | Stima della posa | Il segnale sono gli angoli di ginocchia e anche |
| Contare le barche ormeggiate riprese da un drone | OBB | Le barche sono disposte in diagonale e ravvicinate |
| Pacchi su un nastro trasportatore, ripresi dall’alto | OBB | L’orientamento varia e gli oggetti vicini si toccano |
| Auto a livello della strada | Rilevamento | Le auto appaiono più o meno verticali nell’inquadratura |
Pose aggiunge keypoint a ogni riquadro; OBB aggiunge un angolo. Se il tuo codice non legge mai i keypoint o l'angolo, un semplice rilevatore è più rapido da etichettare, da eseguire e più facile da correggere.
Mostra la soluzione
from ultralytics import YOLO
image = "https://ultralytics.com/images/boats.jpg"
upright = YOLO("yolo26n.pt")(image, verbose=False)[0]
rotated = YOLO("yolo26n-obb.pt")(image, verbose=False)[0]
print(f"axis-aligned detector: {len(upright.boxes)} boxes")
print(f"OBB model: {len(rotated.obb)} rotated boxes")axis-aligned detector: 0 boxes
OBB model: 173 rotated boxesLa maggior parte della differenza dipende dai dati di addestramento, non dalla geometria. yolo26n.pt è stato addestrato su COCO, dove le barche sono perlopiù fotografate di lato; dall’alto non rileva nulla con la soglia predefinita (abbassa conf a 0.05 e ne identifica alcune come bottiglie). Il modello OBB è stato addestrato su immagini aeree. Anche la geometria conta: persino un rilevatore addestrato su immagini aeree di barche disegnerebbe riquadri circa due volte più grandi e avrebbe difficoltà con NMS in file molto ravvicinate. Sia l’attività sia i dati di addestramento devono corrispondere alla vista prevista in produzione.