Estimativa de pose e OBB
Leia os pontos-chave e as caixas rotacionadas do YOLO26, escreva uma regra com base em cada um e reconheça quando a postura ou o ângulo são o verdadeiro sinal.
Uma casa de repouso precisa saber quando alguém caiu; um porto precisa contar navios amontoados lado a lado em uma imagem de drone. Caixas simples falham nos dois casos: uma caixa não indica se uma pessoa está de pé, e uma caixa vertical ao redor de um navio na diagonal é, em sua maior parte, água. A estimativa de pose e o OBB foram desenvolvidos exatamente para esses dois problemas.
Prático
Pose: quando a postura é o sinal#

Um modelo de pose retorna uma caixa para cada pessoa, além de uma lista fixa de pontos-chave. Os modelos treinados com COCO-Pose preveem 17 por pessoa — nariz, olhos, orelhas, ombros, cotovelos, pulsos, quadris, joelhos e tornozelos — sempre na mesma ordem, então o índice 0 é o nariz, o 11 é o quadril esquerdo e o 15 é o tornozelo esquerdo. Cada ponto-chave também tem uma confiança.
A regra útil mais simples: um corpo em pé é mais alto do que largo; um corpo deitado no chão é mais largo do que alto. Veja como ela funciona na imagem do ônibus, usando apenas os pontos-chave nos quais o modelo confia:
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 -> unknownTrês pessoas estão claramente de pé. As duas últimas linhas correspondem à pessoa cortada na borda esquerda e a uma duplicata com baixa confiança: com apenas um ou dois pontos-chave visíveis, não há como avaliar, então a regra retorna "desconhecido" em vez de adivinhar. Um detector de quedas para produção acrescenta o fator tempo — estar deitado por mais de alguns segundos após uma queda rápida — por meio do rastreamento.
Sintoma: esqueletos com pulsos no ar e regras de postura que são acionadas por pessoas parcialmente visíveis. Causa: keypoints.xy retorna uma posição para os 17 pontos-chave, até para os que o modelo não conseguiu ver. Solução: filtre com keypoints.conf, como acima, e exija um número mínimo de pontos-chave visíveis antes de tomar qualquer decisão.
A pose é útil quando a resposta depende do que o corpo está fazendo: quedas ou levantamento de peso com as costas curvadas, por segurança; ângulos das articulações e contagem de repetições em esportes, como no monitoramento de treinos; ou postura de animais de criação e pontos de referência fixos em peças com uma configuração personalizada de pontos-chave. Para responder "há uma pessoa aqui?", use detecção simples.
OBB: quando o ângulo importa#

Uma caixa regular tem bordas paralelas à imagem. Uma caixa delimitadora orientada acrescenta uma rotação, armazenada como centro, largura, altura e ângulo (xywhr). Em imagens de cima — de satélite, drone ou câmeras sobre esteiras transportadoras — os objetos aparecem em todos os ângulos, e uma caixa vertical ao redor de um objeto diagonal contém principalmente o fundo, como aconteceria com os iates acima. Meça a diferença em uma imagem de drone de uma marina:
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)Uma caixa vertical cobre aproximadamente o dobro da área da caixa rotacionada ao redor do mesmo barco, e a área extra é água. Isso causa dois problemas: o NMS considera sobrepostas as caixas verticais de barcos vizinhos e pode suprimir detecções reais, e qualquer estimativa de tamanho fica inflada. Modelos OBB treinados com conjuntos de dados aéreos, como DOTA, lidam diretamente com essas cenas. Observe que o ângulo está em radianos: -0.25 rad equivale a aproximadamente -14°.
Como escolher entre detecção, pose e OBB#
| Cenário | Melhor tarefa | Por quê |
|---|---|---|
| Contar pessoas em uma calçada | Detecção | A resposta é a presença e a localização |
| Detectar uma queda em uma casa de repouso | Pose | A orientação do corpo é o sinal |
| Contar agachamentos em uma academia | Pose | Os ângulos dos joelhos e quadris são o sinal |
| Contar barcos atracados a partir de um drone | OBB | Os barcos ficam na diagonal e muito próximos uns dos outros |
| Pacotes em uma esteira transportadora, vistos de cima | OBB | A orientação varia e os objetos vizinhos se tocam |
| Carros no nível da rua | Detecção | Os carros aparecem aproximadamente na vertical no enquadramento |
Pose adiciona pontos-chave a cada caixa; OBB adiciona um ângulo. Se o seu código nunca lê os pontos-chave nem o ângulo, um detector simples é mais rápido de rotular, mais rápido de executar e mais fácil de depurar.
Mostrar solução
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 boxesA maior parte da diferença se deve aos dados de treinamento, não à geometria. yolo26n.pt foi treinado com COCO, no qual os barcos são fotografados principalmente de lado; vistos de cima, não são detectados no limiar padrão (reduza conf para 0.05 e ele identifica alguns como garrafas). O modelo OBB foi treinado com imagens aéreas. A geometria ainda importa além disso: até um detector treinado com imagens aéreas de barcos desenharia caixas aproximadamente duas vezes maiores e teria dificuldades com o NMS em fileiras muito próximas. Tanto a tarefa quanto os dados de treinamento precisam corresponder à perspectiva de implantação.