Pose-Schätzung und OBB
Lies Keypoints und gedrehte Boxen aus YOLO26 aus, formuliere darauf aufbauend jeweils eine Regel und erkenne, wann die Körperhaltung oder der Winkel das entscheidende Signal ist.
Ein Pflegeheim muss wissen, wenn jemand gestürzt ist; ein Hafen muss Schiffe zählen, die auf einem Drohnenbild dicht nebeneinander liegen. Normale Boxen reichen für beides nicht aus: Eine Box zeigt nicht, ob eine Person aufrecht steht, und eine aufrechte Box um ein diagonal liegendes Schiff enthält größtenteils Wasser. Pose-Schätzung und OBB sind genau für diese beiden Probleme gedacht.
Praxisnah
Pose: wenn die Körperhaltung das Signal ist#

Ein Pose-Modell gibt für jede Person eine Box und eine feste Liste von Keypoints zurück. Modelle, die mit COCO-Pose trainiert wurden, sagen 17 Keypoints pro Person voraus – Nase, Augen, Ohren, Schultern, Ellbogen, Handgelenke, Hüften, Knie und Knöchel – und zwar immer in derselben Reihenfolge. Index 0 ist also die Nase, 11 die linke Hüfte und 15 der linke Knöchel. Jeder Keypoint hat außerdem eine Konfidenz.
Die einfachste nützliche Regel: Ein stehender Körper ist höher als breit; ein auf dem Boden liegender Körper ist breiter als hoch. Hier wird die Regel auf das Busbild angewendet, wobei nur Keypoints verwendet werden, für die das Modell eine hohe Konfidenz hat:
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 -> unknownDrei Personen stehen eindeutig aufrecht. Die letzten beiden Zeilen zeigen die am linken Bildrand abgeschnittene Person und ein Duplikat mit niedriger Konfidenz: Bei nur einem oder zwei sichtbaren Keypoints lässt sich nichts beurteilen, daher gibt die Regel „unbekannt“ aus, anstatt zu raten. Ein Sturzerkennungssystem für den produktiven Einsatz berücksichtigt mithilfe von Tracking auch den zeitlichen Verlauf – etwa, ob jemand nach einem schnellen Sturz länger als einige Sekunden liegen bleibt.
Symptom: Skelette mit Handgelenken in der Luft und Haltungsregeln, die bei halb sichtbaren Personen ausgelöst werden. Ursache: keypoints.xy gibt Positionen für alle 17 Keypoints zurück, auch für solche, die das Modell nicht sehen konnte. Lösung: Filtere mit keypoints.conf wie oben und verlange eine Mindestanzahl sichtbarer Keypoints, bevor du eine Entscheidung triffst.
Pose lohnt sich, wenn die Antwort davon abhängt, was der Körper gerade tut: etwa bei Stürzen oder beim Heben mit gebeugtem Rücken im Arbeitsschutz, bei Gelenkwinkeln und Wiederholungszahlen im Sport wie bei der Trainingsüberwachung oder bei der Körperhaltung von Nutztieren und festen Merkmalen an Bauteilen mit einem benutzerdefinierten Keypoint-Layout. Für die Frage „Ist hier eine Person?“ verwendest du die normale Objekterkennung.
OBB: wenn der Winkel entscheidend ist#

Bei einer normalen Box verlaufen die Kanten parallel zum Bildrand. Eine gedrehte Begrenzungsbox ergänzt eine Drehung, dargestellt durch Mittelpunkt, Breite, Höhe und Winkel (xywhr). In Aufnahmen von oben – etwa von Satelliten, Drohnen oder Überwachungskameras über Förderbändern – liegen Objekte in allen möglichen Winkeln. Eine aufrechte Box um ein diagonales Objekt enthält dann größtenteils Hintergrund, wie bei den Yachten oben. Miss den Unterschied an einer Drohnenaufnahme eines Yachthafens:
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)Eine aufrechte Box deckt etwa die doppelte Fläche der gedrehten Box um dasselbe Boot ab; die zusätzliche Fläche ist Wasser. Das schadet gleich doppelt: NMS erkennt, dass sich die aufrechten Boxen benachbarter Boote überlappen, und kann echte Objekte unterdrücken. Außerdem wird jede Größenschätzung zu hoch angesetzt. OBB-Modelle, die mit Luftbilddatensätzen wie DOTA trainiert wurden, können solche Szenen direkt verarbeiten. Beachte, dass der Winkel in Radiant angegeben wird: -0.25 rad entspricht etwa -14°.
Objekterkennung, Pose oder OBB auswählen#
| Szenario | Geeignete Aufgabe | Warum |
|---|---|---|
| Personen auf einem Gehweg zählen | Detektion | Entscheidend sind Anwesenheit und Position |
| Einen Sturz in einem Pflegeheim erkennen | Pose | Die Körperausrichtung ist das Signal |
| Kniebeugen im Fitnessstudio zählen | Pose | Knie- und Hüftwinkel sind das Signal |
| An einem Steg festgemachte Boote auf einer Drohnenaufnahme zählen | OBB | Die Boote liegen diagonal und dicht nebeneinander |
| Pakete auf einem Förderband, von oben betrachtet | OBB | Die Ausrichtung variiert und benachbarte Objekte berühren sich |
| Autos auf Straßenniveau | Detektion | Autos erscheinen im Bild ungefähr aufrecht |
Pose ergänzt jede Box um Keypoints; OBB ergänzt einen Winkel. Wenn dein Code die Keypoints oder den Winkel nie ausliest, lässt sich ein einfacher Detektor schneller annotieren und ausführen und leichter debuggen.
Lösung anzeigen
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 boxesDer größte Teil des Unterschieds ist auf die Trainingsdaten zurückzuführen, nicht auf die Geometrie. yolo26n.pt wurde mit COCO trainiert, wo Boote meist von der Seite fotografiert werden. In der Ansicht von oben erkennt das Modell bei der Standardschwelle nichts (senke conf auf 0.05, und es stuft einige Boote als Flaschen ein). Das OBB-Modell wurde mit Luftbildern trainiert. Die Geometrie spielt trotzdem zusätzlich eine Rolle: Selbst ein mit Luftbildern von Booten trainierter Detektor würde Boxen zeichnen, die ungefähr doppelt so groß sind, und in dicht gepackten Reihen mit NMS Probleme haben. Sowohl die Aufgabe als auch die Trainingsdaten müssen zur Ansicht im Einsatz passen.