Views
No views yet
| View | Base ViTPose-L (COCO) | This model |
|---|---|---|
| Aerial | 0.818 | 0.993 |
| Front | 0.375 | 0.962 |
| Side above-water | 0.754 | 0.984 |
| Side underwater | 0.613 | 0.989 |
| Side water-level | 0.700 | 0.983 |
| Overall | 0.653 | 0.982 |
vitpose-l-swimxyz-mv.pth — PyTorch checkpoint ({"state_dict", "epoch", "val_pck", "per_view_pck"})vitpose-l-swimxyz-mv.onnx — ONNX export (opset 17, dynamic batch), torch-parity verifiedlifter-swimxyz.pth / .onnx — trained on GT 2D (30.3 mm MPJPE)lifter-swimxyz-realistic.pth / .onnx — trained with the finetuned ViTPose's
measured 2D noise injected — the end-to-end lifter (33.9 mm MPJPE)smpl-regressor-swimxyz.pth / .onnx — from SMPL-24 joints (1.5 mm recon)smpl-regressor-coco.pth / .onnx — from the 12 COCO body joints the lifter
outputs (canonicalized), the piece that closes the loop (5.3 mm recon)stroke-classifier.pth / .onnx — temporal 4-way classifier
(freestyle / backstroke / breaststroke / butterfly) over the 12 COCO body
joints. 100% val accuracy (all four strokes separate cleanly in pose space).
Input (N,27,12,3) canonical body joints → (N,4) stroke logits; gives a
per-frame stroke label for the whole pipeline.video → ViTPose-L 2D (PCK 0.982) → temporal lifter → 3D joints → SMPL body → meshsmpl-regressor-coco
model consumes the lifter's COCO body joints (canonicalized to remove camera
orientation) and outputs SMPL body pose for mesh recovery.3D_cam.txt, camera-space, pelvis-centered) across all five views.| View | MPJPE |
|---|---|
| Aerial | 35 mm |
| Front | 41 mm |
| Side above-water | 32 mm |
| Side underwater | 29 mm |
| Side water-level | 31 mm |
(N, 27, 17, 2) — 27-frame window of screen-normalized 2D keypoints
(VideoPose3D convention: x/w*2-1, y/w*2-h/w), COCO-17 order.(N, 17, 3) — root-relative 3D joints (metres) for the centre frame.1import torch
2from lift_model import TemporalModel # training/src/lift_model.py
3lift = TemporalModel()
4lift.load_state_dict(torch.load("lifter-swimxyz.pth")["state_dict"]); lift.eval()
5xyz = lift(win) # win: (N,27,17,2) -> (N,17,3) metres, root-relative(N, 3, 256, 192) float32, ImageNet-normalized RGB person crop
(top-down — supply a person box from a detector, e.g. YOLO).(N, 17, 64, 48) keypoint heatmaps, COCO-17 joint order.1import torch
2# model definition: https://github.com/JunkyByte/easy_ViTPose (ViTPose class)
3from vit_models.model import ViTPose
4from configs.train_configs.ViTPose_large_coco_256x192 import model as cfg
5
6net = ViTPose(cfg)
7ckpt = torch.load("vitpose-l-swimxyz-mv.pth", map_location="cpu", weights_only=False)
8net.load_state_dict(ckpt["state_dict"])
9net.eval()
10# heatmaps = net(crop) # crop: (N,3,256,192) ImageNet-normalized1import onnxruntime as ort
2sess = ort.InferenceSession("vitpose-l-swimxyz-mv.onnx")
3heatmaps = sess.run(None, {"input": crop_np})[0] # (N,17,64,48)video → 2D → lift → SMPL) is dominated by the lifter
(~30 mm) plus a COCO-17 → SMPL-24 joint-definition gap; wiring that bridge and
fine-tuning on predicted joints is the natural next step.JunkyByte/easy_ViTPose.y_img = H - y); mapped to COCO-17. Validated by overlay.training/ (build → finetune → export).@inproceedings{fiche2023swimxyz, title={SwimXYZ: A large-scale dataset of synthetic swimming motions and videos}, author={Fiche, Gu{\'e}nol{\'e} and others}, year={2023}}
@article{xu2022vitpose, title={ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation}, author={Xu, Yufei and others}, journal={NeurIPS}, year={2022}}