Pose Detection — tehnologie de viziune computerizată care determină poziția corpului uman prin puncte cheie (landmarks): cap, umeri, coate, încheieturi, șolduri, genunchi, glezne. Fiecare punct are coordonate (x, y) în spațiul 2D, iar modelele avansate (MediaPipe BlazePose 3D) adaugă coordonata z pentru adâncime. În aplicațiile mobile, Pose Detection este utilizat în trackere de fitness, aplicații de yoga, filtre AR, programe de reabilitare și sisteme de analiză sportivă. Conform Google ML Kit, 2025, Pose Detection pe dispozitiv procesează până la 30 de cadre pe secundă cu o precizie de 94% PCK.
Principalele
Pose Detection (cunoscut și ca Pose Estimation) se referă la sarcina de a determina punctele cheie semantice ale corpului uman dintr-o imagine sau video. Abordarea Top-down detectează mai întâi persoana (Object Detection), apoi determină poziția acesteia. Abordarea Bottom-up găsește toate landmarks în imagine, apoi le grupează pe persoane (OpenPose). Pentru dispozitivele mobile se folosește bottom-up — este mai rapid atunci când sunt mai multe persoane în cadru. ML Kit și BlazePose utilizează o abordare single-stage — detectare + poziție într-o singură trecere.
COCO Keypoints — set standard de 17 puncte: nas, ochi (2), urechi (2), umeri (2), coate (2), încheieturi (2), șolduri (2), genunchi (2), glezne (2). MediaPipe BlazePose folosește 33 de puncte, adăugând: degete de la picioare, călcâie, centrul trunchiului, puncte faciale. Cu cât mai multe puncte, cu atât analiza poziției este mai precisă, dar sarcina de calcul este mai mare. Pentru aplicații de fitness sunt suficiente 17–20 de puncte. Pentru analiză completă (yoga, dans) — 33 de puncte. Pentru filtre AR — 33 de puncte + 468 de puncte faciale (MediaPipe Face Mesh).
PCK (Percentage of Correct Keypoints) — metrica de precizie a Pose Detection. Se calculează ca proporția punctelor prezise în limita distanței față de ground truth (de obicei 0.05–0.15 din dimensiunea bounding box a persoanei). ML Kit Pose Detection: 94% PCK@0.1. BlazePose Full: 96% PCK@0.1. MoveNet Lightning: 91% PCK@0.1. OKS (Object Keypoint Similarity) — metrică utilizată în COCO, care ia în considerare scara persoanei și dificultatea punctului. mAP@OKS — metrica standard pentru benchmark-uri.
| Model | Landmarks | PCK@0.1 | Latency (GPU) | Dimensiune |
|---|---|---|---|---|
| ML Kit Pose Acc | 33 | 94% | 15–30 ms | 14 MB |
| BlazePose Full | 33 + 3D | 96% | 10–20 ms | 12 MB |
| BlazePose Lite | 33 | 91% | 5–10 ms | 5 MB |
| MoveNet Lightning | 17 | 91% | 8–15 ms | 8 MB |
| MoveNet Thunder | 17 | 95% | 25–40 ms | 13 MB |
Keypoint Visibility: fiecare landmark are un scor (0..1) care indică cât de sigur este modelul de punct și dacă acesta este vizibil. Punctele cu scor < 0.5 sunt considerate invizibile (acoperite, în afara cadrului). Pentru analiza poziției, utilizați doar puncte vizibile. Pentru evaluarea alinierii — calculați distanțele ponderate cu încrederea (confidence-weighted distances), unde punctele cu scor scăzut au o pondere mai mică în metrică.
ML Kit Pose Detection — biblioteca de la Google pentru determinarea poziției pe dispozitiv. Suportă 33 de landmarks, inclusiv puncte faciale, degete de la picioare și călcâie. Moduri: Accurate Mode (model de 14 MB, 15–30 ms, precizie ridicată) și Streaming Mode (5 MB, 5–10 ms, pentru timp real). Streaming Mode utilizează un model ușor cu urmărire — după primul cadru, urmărește mișcarea fără a detecta din nou pozițiile exacte, oferind până la 60 FPS.
API ML Kit Pose Detection: PoseDetector (opțiuni: setDetectorMode, setPerformanceMode) → InputImage → Pose (List<PoseLandmark>). Fiecare PoseLandmark are: landmarkType (38 de tipuri), position (PointF3D), inFrameLikelihood (0..1). Pose oferă, de asemenea: boundingBox-ul persoanei, lista de landmarks, metoda getLandmark(type). Pentru clasificarea poziției, utilizați unghiurile dintre oase: shoulderAngle, elbowAngle, hipAngle — calculate prin Vector3D între landmarks vecine.
val options = PoseDetectorOptions.Builder()
.setDetectorMode(PoseDetectorOptions.STREAM_MODE)
.setPerformanceMode(PoseDetectorOptions.PERFORMANCE_MODE_FAST)
.build()
val detector = PoseDetection.getClient(options)
detector.process(inputImage)
.addOnSuccessListener { pose ->
val leftElbow = pose.getLandmark(PoseLandmark.LEFT_ELBOW)
val leftShoulder = pose.getLandmark(PoseLandmark.LEFT_SHOULDER)
val leftWrist = pose.getLandmark(PoseLandmark.LEFT_WRIST)
val elbowAngle = calculateAngle(
leftShoulder.position, leftElbow.position, leftWrist.position
)
}
ML Kit pe iOS: Pose Detection este disponibil prin ML Kit CocoaPods. API-ul este identic cu Android: PoseDetector → UIImage → Pose → PoseLandmark. Pe iOS, ML Kit utilizează Core ML și ANE (A12+), oferind 10–20 ms latență în Accurate Mode pe iPhone 15 Pro. Streaming Mode — 3–8 ms, până la 120 FPS. Pe iOS, ML Kit Pose Detection funcționează mai rapid decât MediaPipe BlazePose (accelerare Core ML), dar este inferior BlazePose în ceea ce privește numărul de FPS pe dispozitivele mai vechi (iPhone X–11).
MediaPipe BlazePose — model de îndepărtare performant pentru Pose Detection de la Google Research. Utilizează o arhitectură hibridă detector-decoder pipeline bazat pe MobileNetV2 + Feature Pyramid Network. BlazePose Full: 33 landmarks + coordonate 3D (adâncime z). BlazePose Lite: 33 landmarks (2D) fără adâncime. Ambele modele sunt disponibile în MediaPipe Tasks Vision pe Android, iOS, Python și Web. BlazePose Full procesează 30–60 FPS pe GPU, Lite — 60+ FPS.
3D Pose Estimation cu BlazePose: modelul prezice coordonata z pentru fiecare landmark, permițând evaluarea adâncimii (apropierea/depărtarea membrelor) fără cameră stereo. Coordonata z este calculată în spațiu metric (metri) față de cameră. Precizia BlazePose 3D: 37 mm MPJPE (Mean Per Joint Position Error) în benchmark-urile publice — suficientă pentru fitness și AR, insuficientă pentru diagnosticare medicală. Pentru ARKit/ARFoundation, BlazePose 3D oferă adâncime naturală.
// MediaPipe Pose Detection Tasks Vision
val options = PoseLandmarkerOptions.Builder()
.setBaseOptions(BaseOptions.builder()
.setModelAssetPath("pose_landmarker_full.task")
.build())
.setDelegate(Delegate.GPU)
.build()
val landmaker = PoseLandmarker.createFromOptions(context, options)
val result = landmaker.detect(MPImage.fromBitmap(bitmap))
result.landmarks.forEach { pose ->
pose.forEach { landmark ->
drawLandmark(landmark.x, landmark.y, landmark.z)
}
}
BlazePose vs ML Kit Pose Detection: BlazePose este mai rapid (60+ FPS vs 30 FPS), suportă coordonate 3D, funcționează cross-platform prin MediaPipe. ML Kit este mai simplu de integrat (nu necesită MediaPipe SDK), include modele pre-antrenate cu precizie ridicată. Pentru proiecte native iOS — ML Kit Pose Detection (optimizare mai bună pentru ANE). Pentru proiecte cross-platform (Flutter, React Native) — MediaPipe BlazePose (model unic pentru toate platformele). Pentru precizie în scene solicitante — ambele modele sunt comparabile.
MoveNet — familia de modele Pose Detection de la TensorFlow, optimizată pentru TFLite. Lightning (8 MB, INT8 — 4 MB): 17 COCO keypoints, 91% PCK, 8–15 ms latență, 30+ FPS. Thunder (13 MB, INT8 — 6 MB): 17 keypoints, 95% PCK, 25–40 ms latență, 20+ FPS. MoveNet utilizează arhitectura CenterNet + interpolare bilineară pentru heatmap de înaltă rezoluție. MoveNet suportă detectarea multi-pose (până la 6 persoane). Modelele sunt disponibile în TensorFlow Hub.
MoveNet Lightning vs Thunder: Lightning — pentru aplicații în timp real cu FPS ridicat (fitness, filtre AR). Thunder — pentru analiza precisă a poziției (reabilitare, analiză sportivă) pe dispozitive cu GPU. Ambele modele sunt convertite în Core ML prin tf-coreml pentru iOS. MoveNet este disponibil și prin API-ul TFLite Task Vision PoseLandmarker. Recomandare: începeți cu Lightning, dacă precizia este insuficientă — treceți la Thunder (doar +15 ms latență suplimentară).
// MoveNet Inference with TFLite
Interpreter interpreter = new Interpreter(loadModel(context));
TensorImage image = TensorImage.fromBitmap(bitmap);
image.load(Bitmap.createScaledBitmap(bitmap, 192, 192, true));
float[][] output = new float[1][51];
interpreter.run(image.getTensorBuffer(), output);
float[] keypoints = output[0];
for (int i = 0; i < 17; i++) {
float y = keypoints[i * 3];
float x = keypoints[i * 3 + 1];
float score = keypoints[i * 3 + 2];
drawKeypoint(x, y, score);
}
MoveNet Multi-Pose: detectarea a până la 6 persoane în cadru. În locul abordării standard heatmap, MoveNet utilizează person detection + pose refinement: mai întâi detectează persoanele (centroid-based), apoi evaluează poziția fiecăreia. Modul multi-pose este de 2–3x mai lent decât single-pose: Lightning — 25–50 ms (6 persoane). Pentru aplicații de fitness cu un singur utilizator, utilizați single-pose. Pentru activități de grup (yoga, crossfit) — multi-pose cu limitare de cadre pentru economisirea bateriei.
Pose Classification — etapa după detectare: transformarea landmarks în acțiuni semantice (stă în picioare, stă jos, a ridicat mâna, face genuflexiuni). Abordări: Rule-based (reguli manuale — unghiuri între oase), ML-based (regresie logistică sau Random Forest pe vectorul landmarks), DL-based (clasificator LSTM al secvenței de poziții pe cadre). Rule-based — 50–80% precizie, simplu și rapid. ML-based — 85–95% precizie cu 200+ exemple etichetate. LSTM — 90–98% precizie pe serii temporale (video).
Unghiuri între oase: pentru fiecare punct se calculează unghiurile cu punctele vecine. Exemple: right elbow angle (shoulder → elbow → wrist), right knee angle (hip → knee → ankle), torso angle (punctul median al umerilor → punctul median al șoldurilor). Unghiurile sunt invariante la scară și poziția persoanei pe ecran. Normalizarea unghiurilor la intervalul [0, 1] permite clasificarea poziției cu o simplă regulă de prag: dacă elbowAngle < 30° — brațul este îndoit, dacă > 150° — este întins.
// Clasificator de genuflexiuni bazat pe reguli
fun classifySquat(pose: Pose): SquatPhase {
val kneeAngle = angle(
pose.getLandmark(PoseLandmark.LEFT_HIP),
pose.getLandmark(PoseLandmark.LEFT_KNEE),
pose.getLandmark(PoseLandmark.LEFT_ANKLE)
)
return when {
kneeAngle > 140f -> SquatPhase.STANDING
kneeAngle < 90f -> SquatPhase.SQUAT
else -> SquatPhase.TRANSITION
}
}
MediaPipe Pose Classification — clasificatoare pre-antrenate în componența MediaPipe Tasks: genuflexiuni, flotări, plank, ridicări de picioare. Clasificatorul primește o listă de landmarks și returnează acțiunea + încrederea. Include netezire temporală (temporal filter): HED (Holt Exponential Double Smoothing) pentru tranziții line între poziții. Pentru acțiuni personalizate — antrenați un clasificator pe 100–500 de exemple prin MediaPipe Model Maker (TensorFlow Lite + metadata).
Trackere de fitness cu corectarea tehnicii — aplicația analizează poziția utilizatorului în timpul exercițiului și oferă indicații vocale: „coboară pelvisul mai jos”, „nu înclina trunchiul”. ML Kit Pose Detection + clasificator rule-based numără repetițiile și evaluează calitatea. Squat: knee angle < 90° — genuflexiune corectă, back angle < 45° — înclinare periculoasă a trunchiului. Push-up: elbow angle < 90° în punctul inferior — flotare completă. Pull-up: bărbia deasupra nivelului barei.
Reabilitare și fizioterapie — Pose Detection este utilizat pentru controlul de la distanță al exercițiilor de fizioterapie. Medicul stabilește o poziție de referință (de exemplu, abducția umărului la 45°), aplicația măsoară unghiul curent și abaterile. BlazePose 3D oferă o precizie a unghiurilor de ±3° — suficientă pentru evaluare clinică. Frecvență: 1 cadru la 3–5 secunde (economisirea bateriei). On-device — confidențialitatea datelor medicale ale pacientului. Reabilitare după accident vascular cerebral: urmărirea hand-to-shoulder, elbow-extension, hip-flexion.
Filtre AR și efecte — Pose Detection stă la baza filtrelor AR ale rețelelor sociale (TikTok, Instagram, Snapchat). Landmarks ale capului, umerilor și mâinilor sunt utilizate pentru suprapunerea măștilor, animațiilor și elementelor decorative. MediaPipe BlazePose Full + Face Mesh (468 de puncte) oferă 120+ FPS pe dispozitive emblematice. ARKit/ARCore Face Tracking + Pose Detection — combinație pentru full-body AR. Cerințe: FPS > 30, latență motion-to-photon < 20 ms.
// Filtru AR cu landmarks ale poziției
let request = VNDetectHumanBodyPoseRequest { req, _ in
guard let observation = req.results?.first as? VNHumanBodyPoseObservation else { return }
let keypoints = try observation.recognizedPoints(.all)
let rightShoulder = keypoints[VNHumanBodyPoseObservation.JointName.rightShoulder]
DispatchQueue.main.async {
arView.placeFilter(at: rightShoulder?.location ?? .zero)
}
}
Analiză sportivă — evaluarea profesionistă a tehnicii: analiză biomecanică a alergării (cadence, stride length, arm swing symmetry), înotului (body roll, elbow angle la tracțiune), tenisului (shoulder rotation, wrist snap). MoveNet Thunder cu post-procesare oferă suficientă precizie pentru analiză neprofesionistă. Pentru sportul profesionist este necesar 3D Motion Capture (Vicon, OptiTrack), dar Pose Detection pe telefon este o alternativă accesibilă pentru piața de masă. Sincronizarea unghiurilor între cadre — componentă cheie.
Întrebări frecvente
Utilizați temporal smoothing (neteziere temporală): One Euro Filter (filtru 1€) — frecvența de tăiere (cut-off frequency) se configurează separat pentru fiecare landmark, suprimând zgomotul de înaltă frecvență (vibrația), păstrând mișcarea reală (latență scăzută). MediaPipe BlazePose include HED încorporat (Holt Exponential Double Smoothing) — neteziere adaptivă cu predicție a mișcării. Pentru ML Kit, implementați filtrul 1€ manual: filtrul are doi parametri — beta (viteză) și minCutoff (prag de frecvență). Recomandați: beta = 0.04, minCutoff = 0.5 (Android).
ML Kit Pose Detection — o persoană (single-pose). MoveNet Lightning — până la 6 persoane (multi-pose). MediaPipe BlazePose — până la 2–3 persoane prin MediaPipe Tasks (multi-pose). Pentru aplicații cu activități de grup, utilizați MoveNet Lightning sau BlazePose. Pentru aplicații de fitness cu un singur utilizator — ML Kit (integrare mai simplă, precizie mai mare single-pose). Pentru apeluri video cu filtre AR — este suficient BlazePose Lite cu multi-pose (FPS ridicat).
Unghiul dintre două oase: luați trei landmarks — articulația A, articulația B (vârful unghiului), articulația C. Calculați vectorii BA = (A - B) și BC = (C - B). Unghiul = atan2(cross(BA, BC), dot(BA, BC)). Math.toDegrees(acos(dot(BA, BC) / (len(BA) * len(BC)))). Unghiul în intervalul 0–180°. Pentru coordonate tridimensionale (BlazePose 3D) utilizați Vector3D. Normalizați unghiurile în intervalul [0,1] pentru clasificatorul ML.
Da, toate modelele principale (ML Kit, BlazePose, MoveNet) detectează landmarks ale ambelor mâini simultan: LEFT_SHOULDER, LEFT_ELBOW, LEFT_WRIST, RIGHT_SHOULDER, RIGHT_ELBOW, RIGHT_WRIST. Pentru detectarea suplimentară a mâinilor (hand tracking), combinați Pose Detection + Hand Landmarker (21 de puncte pentru fiecare mână). MediaPipe Hands + BlazePose — combinația standard pentru full-body + hands. Pe iOS — VNDetectHumanHandPoseRequest + VNDetectHumanBodyPoseRequest.
ML Kit Pose Detection: bounding box minim al persoanei — 100x100 pixeli (raport ~1:1). MoveNet Lightning: 120x120 pixeli. BlazePose: 80x160 pixeli (bounding box vertical). Pentru o persoană la înălțimea reală la 3 metri distanță de cameră (1920x1080) — aproximativ 250x600 px, ceea ce este suficient. La distanță > 5 metri, precizia scade — utilizați Multi-Pose + high-resolution input. Pentru obiecte îndepărtate, este mai bine să utilizați Object Detection + Pose Estimation (two-stage).
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și