Faza 04 · lecția 21
Detectarea punctelor-cheie și estimarea poziției
Scopul lecției: O poziție (pose) este o mulțime ordonată de puncte-cheie. Un detector de puncte-cheie este un regresor de hărți termice. Restul este gestionarea detaliilor.
Versiunea curentă AlexBred.com: primele 100 de lecții ale programului în limba română.
Cuprinsul lecției
- Obiective de învățare
- Problema
- Conceptul
- Top-down vs bottom-up
- Regresia hărților termice
- Localizare sub-pixel
- Câmpuri de afinitate ale părților (PAF)
- Puncte-cheie COCO
- 2D vs 3D
- Construiți
- Pasul 1: țintă Gaussiană pentru harta termică
- Pasul 2: cap mic pentru puncte-cheie
- Pasul 3: inferență — extrageți coordonatele punctelor-cheie
- Pasul 4: set de date sintetic cu puncte-cheie
- Pasul 5: antrenare
- Utilizați
- Livrați
- Exerciții
- Termeni-cheie
- Lecturi suplimentare
O poziție (pose) este o mulțime ordonată de puncte-cheie. Un detector de puncte-cheie este un regresor de hărți termice. Restul este gestionarea detaliilor.
Tip: Construiți Limbaje: Python Cerințe prealabile: Faza 4 Lecția 06 (Detecție), Faza 4 Lecția 07 (U-Net) Timp: ~45 de minute
Obiective de învățare
- Deosebiți estimarea poziției de sus în jos (top-down) de cea de jos în sus (bottom-up) și precizați când se folosește fiecare
- Estimați prin regresie hărți termice pentru K puncte-cheie cu o țintă Gaussiană pentru fiecare punct-cheie și extrageți coordonatele punctelor-cheie la inferență
- Explicați câmpurile de afinitate ale părților (Part Affinity Fields, PAF) și modul în care fluxurile bottom-up asociază punctele-cheie în instanțe
- Utilizați MediaPipe Pose sau MMPose pentru estimarea punctelor-cheie în producție și înțelegeți formatul ieșirii lor
Problema
Sarcinile cu puncte-cheie apar sub multe denumiri: poziția corpului uman (17 articulații), repere faciale (68 sau 478 de puncte), mână (21 de puncte), poziția animalelor, poziția obiectelor robotice, repere anatomice medicale. Toate au aceeași structură: detectați K puncte discrete pe un obiect și furnizați coordonatele lor (x, y).
Estimarea poziției este baza capturii de mișcare, a aplicațiilor de fitness, analizei sportive, controlului prin gesturi, animației, probării în realitate augmentată (AR) și prinderii robotice. Cazul 2D este matur; poziția 3D (estimarea pozițiilor articulațiilor în coordonate globale dintr-o singură cameră) este frontiera actuală a cercetării.
Întrebarea inginerească ține de scară. Estimarea poziției unei singure persoane dintr-o singură imagine este o problemă de 20 ms. Estimarea poziției mai multor persoane într-o mulțime, la 30 fps, este o problemă diferită, cu arhitecturi diferite.
Notă tehnică a traducerii: O latență de 20 ms nu este o proprietate generală a estimării poziției unei persoane: ea depinde de model, rezoluție, preprocesare, hardware, runtime și de măsurarea capăt-la-capăt. Tratați valoarea ca exemplu orientativ, nu ca buget de performanță garantat.
Conceptul
Top-down vs bottom-up
- Top-down — detectați mai întâi persoanele, apoi rulați un model de puncte-cheie pentru fiecare persoană pe fiecare decupaj. Acuratețe maximă; costul crește liniar cu numărul de persoane.
- Bottom-up — o singură trecere directă prezice toate punctele-cheie, plus un câmp de asociere; apoi grupați-le. Timp constant, indiferent de dimensiunea mulțimii.
Top-down (HRNet, ViTPose) conduce la acuratețe; bottom-up (OpenPose, HigherHRNet) conduce la debit pentru scene aglomerate.
Notă tehnică a traducerii: O trecere directă bottom-up are, de regulă, costul rețelei independent de numărul de persoane, dar extragerea candidaților și gruparea lor pot crește cu numărul de detecții. Nici „acuratețe maximă”, nici „conduce la debit” nu sunt ierarhii permanente: ele depind de setul de date, arhitectură, rezoluție, implementare, hardware și protocolul de evaluare.
Regresia hărților termice
În loc să estimați direct prin regresie (x, y), preziceți o hartă termică H x W pentru fiecare punct-cheie, cu o pată Gaussiană centrată pe poziția reală.
target[k, y, x] = exp(-((x - cx_k)^2 + (y - cy_k)^2) / (2 sigma^2))
La inferență, argmax-ul fiecărei hărți termice este poziția prezisă a punctului-cheie.
De ce hărțile termice funcționează mai bine decât regresia directă: structura spațială a rețelei (harta convoluțională de caracteristici) se aliniază natural cu ieșirea spațială. Țintele Gaussiene regularizează, de asemenea — o eroare mică de localizare produce o pierdere mică, nu zero.
Notă tehnică a traducerii: Hărțile termice sunt frecvente, dar nu sunt universal superioare regresiei de coordonate. Regresia integrală și DSNT, de exemplu, extrag coordonate continue din distribuții spațiale diferențiabile. Alegerea reprezentării depinde de rezoluție, precizia dorită, memorie, setul de date și decoder.
Localizare sub-pixel
Argmax oferă coordonate întregi. Pentru precizie sub-pixel, rafinați prin ajustarea unei parabole la argmax și vecinii săi sau utilizați direcția bine cunoscută a deplasării (dx, dy) = 0.25 * (heatmap[y, x+1] - heatmap[y, x-1], ...).
Notă tehnică a traducerii: Expresia cu
0.25este o euristică de deplasare, nu o ajustare parabolică completă și necesită verificarea marginilor hărții termice. DARK propune codificare sub-pixel nebiasedă și decodare conștientă de distribuție, cu modulare Gaussiană și rafinare prin dezvoltare Taylor; nu considerați formula abreviată drept implementarea exactă a acestei metode.
Câmpuri de afinitate ale părților (PAF)
Trucul OpenPose pentru asocierea bottom-up. Pentru fiecare pereche de puncte-cheie conectate (de exemplu, umărul stâng cu cotul stâng), preziceți un câmp cu 2 canale care codifică vectorul unitar orientat de la unul la celălalt. Pentru a asocia un umăr cu cotul său, integrați PAF-ul de-a lungul liniei care leagă perechile candidate; perechea cu integrala cea mai mare este asociată.
Pentru fiecare conexiune (segment):
Canale PAF: 2 (vector unitar x, y)
Integrală de linie: suma, pe punctele eșantionate, a produsului scalar (PAF · direcția liniei)
Integrală mai mare = corespondență mai puternică
Elegant și extensibil la mulțimi de dimensiuni arbitrare, fără decupaje pentru fiecare persoană.
Puncte-cheie COCO
Setul de date standard pentru poziția corpului: 17 puncte-cheie pentru fiecare persoană, PCK (Percentage of Correct Keypoints, procentul punctelor-cheie corecte) și OKS (Object Keypoint Similarity) drept metrici. OKS este analogul pentru puncte-cheie al IoU și este cel pe care îl raportează COCO mAP@OKS.
Notă tehnică a traducerii: În evaluarea oficială COCO pentru puncte-cheie, AP și AR se calculează pe praguri OKS; PCK este o metrică răspândită în estimarea poziției, dar nu este metrica oficială COCO pentru mAP. De asemenea, OKS este o măsură de similitudine inspirată de IoU, nu IoU calculat direct pe puncte.
2D vs 3D
- Poziție 2D — coordonate în imagine; rezolvată la calitate de producție (MediaPipe, HRNet, ViTPose).
- Poziție 3D — coordonate globale / ale camerei; încă domeniu activ de cercetare. Abordări comune:
- Ridicați predicțiile 2D la 3D cu un MLP mic (VideoPose3D).
- Regresie 3D directă din imagine (PyMAF, MHFormer).
- Configurații multi-view (CMU Panoptic) pentru adevărul de referință.
Notă tehnică a traducerii: „Calitate de producție” nu este un prag formal și trebuie validată pe datele, numărul de persoane, ocluziile, camera și cerințele aplicației. Coordonatele 3D furnizate de un sistem monocular pot folosi sisteme de referință specifice modelului; ele nu echivalează automat cu poziții metrice globale calibrate. VideoPose3D ridică secvențe temporale de puncte 2D prin convoluții temporale, nu printr-un MLP pentru o singură imagine; PyMAF recuperează poziția și forma 3D prin alinierea unei plase parametrice, iar MHFormer operează asupra unor secvențe de poziții 2D. Aceste exemple nu sunt aceeași interfață de „regresie directă din imagine”.
Construiți
Pasul 1: țintă Gaussiană pentru harta termică
import numpy as np
import torch
def gaussian_heatmap(size, cx, cy, sigma=2.0):
yy, xx = np.meshgrid(np.arange(size), np.arange(size), indexing="ij")
return np.exp(-((xx - cx) ** 2 + (yy - cy) ** 2) / (2 * sigma ** 2)).astype(np.float32)
hm = gaussian_heatmap(64, 32, 32, sigma=2.0)
print(f"peak: {hm.max():.3f} at ({hm.argmax() % 64}, {hm.argmax() // 64})")
Hărțile termice pentru fiecare punct-cheie, stivuite de-a lungul axei canalelor, formează tensorul-țintă complet.
Pasul 2: cap mic pentru puncte-cheie
Un model în stil U-Net care produce K canale de hărți termice.
import torch.nn as nn
import torch.nn.functional as F
class TinyKeypointNet(nn.Module):
def __init__(self, num_keypoints=4, base=16):
super().__init__()
self.down1 = nn.Sequential(nn.Conv2d(3, base, 3, 2, 1), nn.ReLU(inplace=True))
self.down2 = nn.Sequential(nn.Conv2d(base, base * 2, 3, 2, 1), nn.ReLU(inplace=True))
self.mid = nn.Sequential(nn.Conv2d(base * 2, base * 2, 3, 1, 1), nn.ReLU(inplace=True))
self.up1 = nn.ConvTranspose2d(base * 2, base, 2, 2)
self.up2 = nn.ConvTranspose2d(base, num_keypoints, 2, 2)
def forward(self, x):
h1 = self.down1(x)
h2 = self.down2(h1)
h3 = self.mid(h2)
u1 = self.up1(h3)
return self.up2(u1)
Intrare (N, 3, H, W), ieșire (N, K, H, W). Pierderea este MSE per pixel față de țintele Gaussiene.
Notă tehnică a traducerii: Pentru acest
TinyKeypointNet, forma ieșirii coincide cu(N, K, H, W)când înălțimea și lățimea sunt multipli de 4, cum este cazul exemplului 64 × 64. În general, cele două convoluții cu stride 2 și cele două convoluții transpuse produc dimensiuni dependente de rotunjire; verificați forma efectivă și alinierea grilei dintre predicție și țintă înainte de calculul pierderii.
Pasul 3: inferență — extrageți coordonatele punctelor-cheie
def heatmap_to_coords(heatmaps):
"""
heatmaps: (N, K, H, W)
returns: (N, K, 2) float coordinates in image pixels
"""
N, K, H, W = heatmaps.shape
hm = heatmaps.reshape(N, K, -1)
idx = hm.argmax(dim=-1)
ys = (idx // W).float()
xs = (idx % W).float()
return torch.stack([xs, ys], dim=-1)
coords = heatmap_to_coords(torch.randn(2, 4, 32, 32))
print(f"coords: {coords.shape}") # (2, 4, 2)
O singură linie la inferență. Pentru rafinare sub-pixel, interpolați în jurul argmax-ului.
Notă tehnică a traducerii: Funcția întoarce coordonate în grila hărții termice, nu automat pixeli în imaginea originală. Pentru un flux real, transformați coordonatele invers prin factorul de stride și prin toate decupările, redimensionările, paddingul și eventualele transformări afine aplicate intrării.
Pasul 4: set de date sintetic cu puncte-cheie
Simplu: desenați patru puncte pe o pânză albă și învățați să le preziceți.
def make_synthetic_sample(size=64):
img = np.ones((3, size, size), dtype=np.float32)
rng = np.random.default_rng()
kps = rng.integers(8, size - 8, size=(4, 2))
for cx, cy in kps:
img[:, cy - 2:cy + 2, cx - 2:cx + 2] = 0.0
hms = np.stack([gaussian_heatmap(size, cx, cy) for cx, cy in kps])
return img, hms, kps
Suficient de simplu pentru ca un model mic să învețe într-un minut.
Notă tehnică a traducerii: Eșantionul sintetic nu modelează vizibilitatea sau ocluziile. În COCO, fiecare punct-cheie are un indicator de vizibilitate; un flux real trebuie să mascheze pierderea pentru punctele neetichetate și să decidă explicit cum supraveghează punctele ocluzate, în loc să le trateze automat ca fundal.
Notă tehnică a traducerii: Timpul de antrenare nu este garantat: el variază cu hardware-ul, versiunea bibliotecilor, dimensiunea lotului și aleatoritatea inițializării. Folosiți convergența pierderii și eroarea de localizare, nu durata fixă, drept criterii de reușită.
Pasul 5: antrenare
model = TinyKeypointNet(num_keypoints=4)
opt = torch.optim.Adam(model.parameters(), lr=3e-3)
for step in range(200):
batch = [make_synthetic_sample() for _ in range(16)]
imgs = torch.from_numpy(np.stack([b[0] for b in batch]))
hms = torch.from_numpy(np.stack([b[1] for b in batch]))
pred = model(imgs)
# Upsample pred to full resolution
pred = F.interpolate(pred, size=hms.shape[-2:], mode="bilinear", align_corners=False)
loss = F.mse_loss(pred, hms)
opt.zero_grad(); loss.backward(); opt.step()
Utilizați
- MediaPipe Pose — estimatorul de poziție pentru producție de la Google; oferă runtime-uri WebGL și mobile cu latență sub 10 ms.
- MMPose (OpenMMLab) — bază de cod cuprinzătoare pentru cercetare; fiecare arhitectură SOTA cu ponderi preantrenate.
- YOLOv8-pose — cea mai rapidă estimare în timp real a poziției mai multor persoane cu o singură trecere directă.
- transformers HumanDPT / PoseAnything — abordări mai noi limbaj–viziune pentru poziție cu vocabular deschis (orice obiect, orice set de puncte-cheie).
Notă tehnică a traducerii: MediaPipe Pose Landmarker documentează intrări pentru imagini, cadre video și fluxuri live, precum și repere în coordonate de imagine și globale; nu garantează aici latența „sub 10 ms”. MMPose oferă un catalog extins de modele, nu o enumerare a fiecărei arhitecturi SOTA. „Cea mai rapidă” pentru YOLOv8-pose este o afirmație dependentă de modelul exact, rezoluție, lot, hardware și protocol; măsurați pe sarcina-țintă înainte de alegerea stackului. În documentația
transformers, DPT este un Dense Prediction Transformer pentru estimarea adâncimii și segmentare semantică, nu un estimator generic de poziție. PoseAnything este un model CAPE 2D care localizează puncte-cheie definite prin imagini-suport adnotate; nu este un model general limbaj–viziune care primește liber orice prompt textual.
Livrați
Această lecție produce:
outputs/prompt-pose-stack-picker.md— un prompt care alege MediaPipe / YOLOv8-pose / HRNet / ViTPose în funcție de latență, dimensiunea mulțimii și necesarul 2D versus 3D.outputs/skill-heatmap-to-coords.md— o competență care scrie rutina de conversie sub-pixel din hartă termică în coordonate, utilizată de fiecare model de poziție pentru producție.
Notă tehnică a traducerii: Rutina argmax pentru hartă termică este un exemplu didactic, nu o componentă a fiecărui model de poziție pentru producție. Unele arhitecturi folosesc hărți termice cu rafinare, iar altele prezic coordonate, distribuții sau clasificări de coordonate prin alte reprezentări.
Exerciții
- (Ușor) Antrenați modelul mic de puncte-cheie pe setul de date sintetic cu 4 puncte. Raportați eroarea L2 medie dintre punctele-cheie prezise și cele reale după 200 de pași.
- (Mediu) Adăugați rafinarea sub-pixel: pentru poziția argmax, ajustați o parabolă 1D de-a lungul axelor x și y din pixelii vecini. Raportați câștigul de acuratețe față de argmax-ul întreg.
- (Dificil) Construiți un set de date sintetic cu 2 persoane, în care fiecare imagine arată două instanțe ale tiparului cu 4 puncte-cheie. Antrenați un flux bottom-up cu PAF-uri care prezice ce punct-cheie aparține fiecărei instanțe și evaluați OKS.
Termeni-cheie
| Termen | Ce spun oamenii | Ce înseamnă de fapt |
|---|---|---|
| Punct-cheie | „Un reper” | Un punct specific ordonat pe un obiect (articulație, colț, caracteristică) |
| Poziție | „Scheletul” | O mulțime ordonată de puncte-cheie care aparțin unei instanțe |
| Top-down | „Detectați, apoi poziția” | Flux în două etape: detector de persoane + model de puncte-cheie pentru fiecare decupaj; acuratețe maximă |
| Bottom-up | „Mai întâi poziția, grupați ulterior” | Predicție cu o singură trecere a tuturor punctelor-cheie + grupare; timp constant în raport cu dimensiunea mulțimii |
| Hartă termică | „Țintă Gaussiană” | Tensor H x W pentru fiecare punct-cheie, cu maxim în poziția reală; ținta de regresie preferată |
| PAF | „Part Affinity Field” | Câmp de vectori unitari cu 2 canale care codifică direcțiile segmentelor; folosit pentru gruparea punctelor-cheie în instanțe |
| OKS | „IoU pentru puncte-cheie” | Object Keypoint Similarity; metrica COCO pentru poziție |
| HRNet | „Rețea de înaltă rezoluție” | Arhitectura dominantă top-down pentru puncte-cheie; păstrează caracteristici de înaltă rezoluție pe tot parcursul |
Notă tehnică a traducerii: Formulările „ținta preferată”, „arhitectura dominantă” și „SOTA actual” sunt dependente de sarcină, benchmark, rezoluție, buget de calcul și momentul evaluării. Lucrarea ViTPose raportează rezultate pentru benchmarkurile și protocolul său; ea nu stabilește un clasament permanent pentru toate aplicațiile de estimare a poziției.
Lecturi suplimentare
- OpenPose (Cao et al., 2017) — bottom-up cu PAF-uri; încă cea mai bună prezentare a abordării
- HRNet (Sun et al., 2019) — arhitectura de referință top-down
- ViTPose (Xu et al., 2022) — ViT simplu drept backbone pentru poziție; SOTA actual pe multe benchmarkuri
- MediaPipe Pose — poziție în timp real pentru producție; cel mai rapid stack implementat în 2026
Sursă: Originalul în limba engleză
Navigare: ← Lecția 04.20 — Regăsirea imaginilor și învățarea metrică · Faza 4 — Viziune computerizată · Lecția 04.22 — 3D Gaussian Splatting de la zero → · Catalog complet