[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-79078":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},79078,"SAM3DBody-cpp","AmmarkoV\u002FSAM3DBody-cpp","AmmarkoV","Real-time 3D full-body reconstruction from a single camera, Multiperson BVH output, Pure C++ runtime, ONNX + ggml, 70-joint skeleton with hands.",null,"C",511,68,3,5,0,7,40,478,32,9.52,"MIT License",false,"main",true,[],"2026-06-12 02:03:49","# SAM3DBody-cpp\n\nStandalone C++ inference engine for **SAM-3D-Body** — zero Python dependency at runtime.\n\nTakes a BGR image and produces per-person MHR body pose parameters, camera translation, and optionally full 3D mesh vertices + 70 body\u002Fhand keypoints, all via ONNX Runtime + ggml.\n\nAlso includes Python frontends that call the compiled shared library via ctypes, and a CSV exporter for the 70 MHR keypoints.\n\n### 🎬 Multi-person BVH motion-capture export\n\n`--bvh PATH` writes a **standard BVH motion-capture file per detected person** (`p_0.bvh`, `p_1.bvh`, …).\nIdentities are kept stable across frames by a built-in 2D-bbox IoU tracker, each\nfile's joint OFFSETs are auto-resized to the actor's measured bone lengths, and the\noutput drops straight into Blender \u002F BVHTester \u002F any DCC. A bundled\n[`blender\u002Fblender_bvh_plugin.py`](blender\u002Fblender_bvh_plugin.py) drives a\nMakeHuman-rigged character from the result. See **[BVH export](#bvh-export---bvh)** for details.\n\n```bash\n.\u002Ffast_sam_3dbody_run --from clip.mp4 --bvh .\u002Fp.bvh --headless\n# → p_0.bvh, p_1.bvh, …\n```\n\n![SAM3DBody-cpp](doc\u002Fscreen.jpg)\n\n---\n\n## Models\n\nPre-built ONNX \u002F GGUF \u002F LBS model files are hosted on HuggingFace:\n\n**[https:\u002F\u002Fhuggingface.co\u002FAmmarkoV\u002FSAM3DBody-cpp-onnx-models](https:\u002F\u002Fhuggingface.co\u002FAmmarkoV\u002FSAM3DBody-cpp-onnx-models)**\n\nDownload `SAM3DBody-cpp-onnx-models.zip`, extract it, and place the resulting `onnx\u002F` directory at the root of this repository:\n\n```bash\n# Download and extract\nwget https:\u002F\u002Fhuggingface.co\u002FAmmarkoV\u002FSAM3DBody-cpp-onnx-models\u002Fresolve\u002Fmain\u002FSAM3DBody-cpp-onnx-models.zip\nunzip SAM3DBody-cpp-onnx-models.zip\n# onnx\u002F is now at the repo root — ready to build\n```\n\n| File | Size | Description |\n|------|------|-------------|\n| `onnx\u002Fbackbone.onnx` + `.data` | ~4.8 GB | DINOv3-ViT-H\u002F14+ encoder |\n| `onnx\u002Fdecoder.onnx` | ~93 MB | 6-layer PromptableDecoder |\n| `onnx\u002Fyolo.onnx` | ~81 MB | YOLO11m-pose person detector |\n| `onnx\u002Fpipeline.gguf` | ~5 MB | MHR + camera projection heads |\n| `onnx\u002Fbody_model.lbs` | ~27 MB | Native C LBS data (joints, weights, shape) |\n| `onnx\u002Fcorrectives.bin` | ~33 MB | Pose corrective blend shapes |\n| `onnx\u002Fkeypoint_mapping.bin` | ~8 KB | MHR-70 keypoint index map |\n\n> **CMake will warn** at configure time if neither `onnx\u002F` nor the zip is found.\n\n---\n\n## Pipeline\n\n```\nBGR image\n  │\n  ▼  yolo.onnx            ONNX Runtime (CUDA EP)   person bboxes + 17 COCO keypoints\n  │\n  ▼  backbone.onnx        ONNX Runtime (CUDA EP)   feature map  [B, 1280, 32, 32]\n  │   DINOv3-ViT-H\u002F14+\n  │\n  ▼  decoder.onnx         ONNX Runtime (CUDA EP)   pose token   [B, 1024]\n  │   6-layer PromptableDecoder\n  │\n  ▼  pipeline.gguf        CPU matmul (ggml)         MHR params [B, 519] + camera [B, 3]\n  │   MHR head + camera head weights\n  │\n  ▼  body_model.lbs       native C LBS (optional)   vertices [18439, 3] in metres\n      extracted once by tools\u002Fextract_lbs_data.py\n```\n\n> **Note:** `body_model.onnx` export is blocked on PyTorch ≥ 2.x (torch.export rejects\n> TorchScript modules). The native C LBS path reads `body_model.lbs` directly and\n> produces identical output to Python `mhr_forward` (body model stores data in cm;\n> `mhr_lbs_compute` applies ×0.01 to match Python's `\u002F100` conversion).\n\n**Per-person output** (`MHRResult` \u002F `FsbResult`):\n\n| Field | Shape | Description |\n|-------|-------|-------------|\n| `bbox` | [4] | x1 y1 x2 y2 in original image pixels |\n| `focal_length` | scalar | Estimated focal length (pixels) |\n| `pred_cam_t` | [3] | Raw camera head output: [s, tx, ty] |\n| `global_rot` | [3] | Global orientation – Euler ZYX (radians) |\n| `body_pose` | [133] | Body joint angles – Euler |\n| `shape` | [45] | SMPL-like identity blend shape betas |\n| `scale` | [28] | Scale PCA components |\n| `hand_pose` | [108] | Hand joints: left [54] + right [54] |\n| `face_params` | [72] | Facial expression parameters |\n| `mhr_model_params` | [204] | Assembled LBS parameter vector (passed to `mhr_lbs_compute`) |\n| `yolo_kps` | [51] | COCO 17 keypoints × [x, y, confidence] |\n| `pred_vertices` | [55317] | 18439 verts × 3, metres (when native C LBS runs) |\n| `kps_3d` | [210] | 70 joints × 3, metres (when native C LBS runs) |\n| `kps_2d` | [140] | 70 joints × 2 projected (when native C LBS runs) |\n\n---\n\n## Directory layout\n\n```\nSAM3DBody-cpp\u002F\n├── CMakeLists.txt\n├── body_mesh.tri                     SMPL-like body mesh for the GL renderer\n├── fast_sam_3dbody_frontend.py       Python lightweight frontend (ctypes, no extra deps)\n├── fast_sam_3dbody_frontend-3D.py    Python 3D frontend (ctypes + Python body model)\n├── fast_sam_3dbody_dump_csv.py       Python CSV exporter – 70 MHR keypoints per frame\n├── two_pass.py                       Second-pass temporal smoother\n├── ros_demo_webcam.py                ROS demo\n├── onnx\u002F                             Runtime model files – download from HuggingFace (see above)\n│   ├── backbone.onnx + .data         ~4.8 GB  DINOv3-ViT-H\u002F14+ encoder\n│   ├── decoder.onnx                  ~93 MB   6-layer PromptableDecoder\n│   ├── pipeline.gguf                 ~5 MB    MHR + camera heads\n│   ├── yolo.onnx                     ~81 MB   YOLO11m-pose\n│   ├── body_model.lbs                ~27 MB   native C LBS data\n│   ├── correctives.bin               ~33 MB   pose corrective blend shapes\n│   └── keypoint_mapping.bin          ~8 KB    MHR-70 keypoint index map\n├── GraphicsEngine\u002F\n│   ├── System\u002Fglx3.{h,c}            GLX window management\n│   └── ModelLoader\u002F                  .tri mesh loader + LBS joint transform\n├── AmMatrix\u002F                         Lightweight C matrix \u002F quaternion library\n├── render\u002F\n│   ├── fast_sam_3dbody_render.cpp    OpenGL mesh overlay renderer\n│   └── mhr_pose_driver.h             LBS driver (camera matrices, vertex update)\n├── scripts\u002F\n│   └── build.sh \u002F setup.sh \u002F webcam.sh \u002F video.sh\n└── src\u002F\n    ├── fast_sam_3dbody.h             C++ public API\n    ├── fast_sam_3dbody.cpp           Pipeline implementation\n    ├── fast_sam_3dbody_capi.h        Plain C API (for ctypes)\n    ├── fast_sam_3dbody_capi.cpp\n    ├── preprocess.hpp                Crop, normalise, ray_cond, NMS, pose conversion\n    ├── bvh_writer.h \u002F bvh_writer.cpp BVH motion-capture exporter (multi-person, name-mapped to MHR joints)\n    ├── mhr_joint_table.h             Generated by scripts\u002Fbuild_joint_table.py — MHR joint names + parents\n    └── main.cpp                      CLI executable (--bvh, --out CSV, live overlay window)\n```\n\n> **Developer tools** (ONNX\u002FGGUF export, LBS extraction, debug scripts, Python training env) live in the parent project:\n> **[https:\u002F\u002Fgithub.com\u002FAmmarkoV\u002FFast-SAM-3D-Body](https:\u002F\u002Fgithub.com\u002FAmmarkoV\u002FFast-SAM-3D-Body)**\n\n---\n\n## Setup\n\n### 1. Download models\n\nSee the **[Models](#models)** section above. After extracting the zip, `onnx\u002F` should be at the repo root.\n\n> To build models from source (requires the original Python training environment), see\n> [Fast-SAM-3D-Body](https:\u002F\u002Fgithub.com\u002FAmmarkoV\u002FFast-SAM-3D-Body).\n\n### 2. Build\n\nRequirements: CMake ≥ 3.18, C++17 compiler, OpenCV (core\u002Fimgproc\u002Fvideoio\u002Fhighgui\u002Fdnn), optional CUDA Toolkit.\n\n```bash\ncd fast_sam_3dbody_cpp\nmkdir -p build && cd build\n\ncmake .. -DCMAKE_BUILD_TYPE=Release\nmake -j$(nproc)\n```\n\nCMake handles dependencies automatically:\n- **ONNX Runtime 1.20.1** – downloaded from GitHub releases if not found; point to an existing install with `-DONNX_RUNTIME_DIR=\u002Fpath\u002Fto\u002Fonnxruntime`\n- **ggml** – fetched via `FetchContent` from GitHub\n- **CUDA** – auto-detected; set `-DCMAKE_CUDA_ARCHITECTURES=86` (or `75`, `89`, etc.) for your GPU; falls back to CPU-only if not found\n\nOutputs in `build\u002F`:\n\n| File | Description |\n|------|-------------|\n| `fast_sam_3dbody_run` | Standalone CLI executable |\n| `libfast_sam_3dbody.so` | Shared library for C++ linking or ctypes |\n\n---\n\n## Running\n\n### CLI executable\n\n```bash\ncd fast_sam_3dbody_cpp\u002Fbuild\n\n# Single image – prints pose params to stdout\n.\u002Ffast_sam_3dbody_run \\\n    --onnx-dir ..\u002Fonnx \\\n    --gguf     ..\u002Fonnx\u002Fpipeline.gguf \\\n    --yolo     ..\u002Fonnx\u002Fyolo.onnx \\\n    --from     ..\u002F..\u002Fassets\u002Fteaser.png\n\n# Webcam (device 0)\n.\u002Ffast_sam_3dbody_run \\\n    --onnx-dir ..\u002Fonnx --gguf ..\u002Fonnx\u002Fpipeline.gguf --yolo ..\u002Fonnx\u002Fyolo.onnx \\\n    --from 0\n\n# Video file\n.\u002Ffast_sam_3dbody_run \\\n    --onnx-dir ..\u002Fonnx --gguf ..\u002Fonnx\u002Fpipeline.gguf --yolo ..\u002Fonnx\u002Fyolo.onnx \\\n    --from \u002Fpath\u002Fto\u002Fvideo.mp4\n\n# Fastest mode – skip LBS body model (no vertices, just pose params)\n.\u002Ffast_sam_3dbody_run ... --skip-body\n\n# CPU-only\n.\u002Ffast_sam_3dbody_run ... --cuda -1\n```\n\nFull option list:\n\n```\n--onnx-dir PATH    Directory with backbone\u002Fdecoder\u002Fbody_model ONNX files\n--gguf     PATH    pipeline.gguf (MHR + camera heads)\n--yolo     PATH    YOLO pose model (.onnx)\n--from     SRC     Webcam index (0,1,..) or path to image\u002Fvideo\n-o \u002F --out PATH    Write 70-joint 3D keypoints to CSV per frame\n--bvh      PATH    Write BVH motion capture file(s) to PATH (see \"BVH export\" below)\n--bvh-template P   BVH skeleton template (default: .\u002Fbody.bvh)\n--cuda     DEVICE  CUDA device index (default 0; -1 = CPU)\n--skip-body        Skip body model (no vertices \u002F keypoints)\n--headless         No display window\n--thresh   T       YOLO person confidence threshold (default 0.50)\n--nms      T       YOLO NMS IoU threshold (default 0.45)\n--fx \u002F --fy F      Camera focal length x\u002Fy in pixels (0 = image width)\n--cx \u002F --cy F      Principal point (0 = image centre)\n--render-size W H  Override display window size\n--size W H         Webcam capture resolution\n--fps Z            Webcam capture framerate\n--butterworth      Apply Butterworth low-pass filter to MHR output vectors\n--bw-cutoff HZ     Butterworth cutoff frequency in Hz (default 6.0)\n--rot-clamp DEG    Max global_rot change per frame in degrees (default 15; 0=off)\n--info             Print pipeline info and exit\n--help             Show this message\n```\n\n### Python lightweight frontend\n\nDraws COCO 2D skeletons and a pose-bar panel. Requires only `opencv-python` and `numpy` — no PyTorch.\n\n```bash\n# From the repo root:\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend.py --from assets\u002Fteaser.png\n\n# Webcam, cap at 3 persons\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend.py --from 0 --max-skeletons 3\n\n# Save output image \u002F video\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend.py \\\n    --from assets\u002Fteaser.png --out out.jpg\n\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend.py \\\n    --from video.mp4 --headless --out out.mp4\n```\n\nKey options (same as CLI, plus):\n\n```\n--max-skeletons N  Cap persons drawn per frame (0 = unlimited)\n--headless         No display window\n--out PATH         Write result to image or video file\n```\n\n### Python 3D frontend\n\nFull 3D mesh rendering identical to `demo_webcam.py`: four-panel output\n`[original | 2D skeleton | front mesh | side mesh]`.\n\nUses the C engine for the fast path (YOLO → backbone → decoder → MHR FFN heads),\nthen calls the Python MHR body model (`mhr_model.pt`) for LBS skinning to produce\nmesh vertices. Requires the full Python environment (PyTorch, sam_3d_body package, pyrender).\n\n```bash\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend-3D.py --from assets\u002Fteaser.png\n\n# Webcam\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend-3D.py --from 0 --max-skeletons 3\n\n# Custom checkpoint paths\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend-3D.py \\\n    --from assets\u002Fteaser.png \\\n    --checkpoint .\u002Fcheckpoints\u002Fsam-3d-body-dinov3\u002Fmodel.ckpt \\\n    --mhr-model  .\u002Fcheckpoints\u002Fsam-3d-body-dinov3\u002Fassets\u002Fmhr_model.pt\n\n# Save result\npython fast_sam_3dbody_cpp\u002Ffast_sam_3dbody_frontend-3D.py \\\n    --from assets\u002Fteaser.png --out result_3d.jpg\n```\n\nKey options (same as lightweight frontend, plus):\n\n```\n--checkpoint PATH  Path to model.ckpt (default: checkpoints\u002Fsam-3d-body-dinov3\u002Fmodel.ckpt)\n--mhr-model  PATH  Path to mhr_model.pt\n--device     STR   PyTorch device for body model: cuda or cpu (default: auto)\n```\n \n\n---\n\n## Output filtering\n\nThe CLI can apply a second-order [Butterworth low-pass filter](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FButterworth_filter)\nto the MHR output vectors on every frame, reducing per-frame jitter without introducing ripple in the\npassband.\n\n```bash\n# Enable with the default 6 Hz cutoff\n.\u002Ffast_sam_3dbody_run --from video.mp4 --butterworth\n\n# Lower cutoff for smoother (more lag) output\n.\u002Ffast_sam_3dbody_run --from video.mp4 --butterworth --bw-cutoff 3.0\n\n# Higher cutoff to preserve faster motion\n.\u002Ffast_sam_3dbody_run --from video.mp4 --butterworth --bw-cutoff 10.0\n```\n\nThe filter is applied in-place to each detected person's result immediately after inference,\nso all downstream consumers (CSV writer, BVH writer, display overlay) receive filtered data.\n\n### Filtered vectors\n\n| Vector | Channels | Method | Description |\n|--------|----------|--------|-------------|\n| `keypoints_3d` | 210 (70 joints × 3) | Butterworth | 3-D joint positions in metres |\n| `body_pose` | 133 | Butterworth | Body joint Euler angles |\n| `hand_pose` | 108 | Butterworth | Hand joint angles (left 54 + right 54) |\n| `global_rot` | 3 | Clamped-delta | Global orientation – Euler ZYX |\n| `pred_cam_t` | 3 | Butterworth | Camera \u002F root translation |\n\n`global_rot` uses **wrap-corrected frame rejection** rather than Butterworth because\nEuler angles wrap at ±π — a Butterworth filter interpolates through the discontinuity\nand produces a visible flip.  Clamping the delta only delays the flip; if the model\nkeeps predicting the flipped orientation the output still slowly drifts there.\n\nInstead, the per-frame wrapped delta is compared to `--rot-clamp`. If any component\nexceeds the threshold the frame is **rejected** and the previous value is held.\nGenuine rotation (small delta per frame) passes through unchanged; flips and\nambiguous orientation jumps (large delta) are frozen out entirely.\n\n### Parameters\n\n| Flag | Default | Notes |\n|------|---------|-------|\n| `--butterworth` | off | Enable the filter |\n| `--bw-cutoff HZ` | `6.0` | Cutoff frequency in Hz. Lower = smoother but more temporal lag. Human motion typically stays below 6 Hz; use 3–4 Hz for very smooth output, 8–10 Hz to preserve fast gestures. |\n| `--rot-clamp DEG` | `15.0` | Per-frame rejection threshold for `global_rot` in degrees. If any Euler component's wrapped delta exceeds this, the frame is discarded and the previous value is held. Prevents flips without drifting toward them. Set to `0` to disable. |\n\nThe sampling rate is taken from `--fps` when specified, otherwise 30 Hz is assumed.\nEach person slot maintains its own independent filter bank; new person slots are\ninitialised with a warm-up pass on their first frame so the filter starts from the\nmeasured value rather than zero.\n\n### Implementation\n\nImplemented in `src\u002FoutputFiltering.h` — a header-only, dependency-free, C-compatible\nButterworth filter. Each channel is a `ButterWorth` struct initialised with\n`initButterWorth(sensor, fs, fc)` and stepped with `filter(sensor, value)`.\n\n---\n\n## BVH export (`--bvh`)\n\nExports the per-frame MHR pose as one or more standard BVH motion-capture files.\nThe hierarchy is taken from a BVH template (default `.\u002Fbody.bvh`, a [MocapNET](https:\u002F\u002Fgithub.com\u002FFORTH-ModelBasedTracker\u002FMocapNET)\u002F[MakeHuman](https:\u002F\u002Fstatic.makehumancommunity.org\u002F)\nT-pose skeleton); the motion comes from the MHR pipeline.\n\n```bash\n# Single image \u002F video \u002F webcam → one or more \u003Cname>_\u003Cid>.bvh files\n.\u002Ffast_sam_3dbody_run --from boom.mp4 --bvh .\u002Fp.bvh --headless\n# produces .\u002Fp_0.bvh, .\u002Fp_1.bvh, … (one per tracked person)\n```\n\n### What gets written\n\nFor each detected person, every frame:\n\n* **Root joint** — translation from `pred_cam_t` (×100 to convert metres → cm)\n  and orientation from MHR's global rotation, in the BVH root's\n  `Zrotation Yrotation Xrotation` channel order.\n* **Body joints** matched by name to MHR (~50 joints incl. spine, arms, legs,\n  fingers — full table in `src\u002Fbvh_writer.cpp` `NAME_MAP`). The local rotation\n  is computed in MHR's frame as `inv(delta[parent]) · delta[self]`, where\n  `delta[j] = R_global_mhr[j] · R_global_mhr_rest[j]⁻¹`, then decomposed to the\n  joint's BVH channel order (`Zrotation Xrotation Yrotation`).\n* **Unmapped BVH joints** (toes, face details, BVH metacarpals, etc.) stay at\n  zero rotation — MHR doesn't predict angles for them.\n* **OFFSETs** are rewritten at close-time to each person's median observed bone\n  length so the template T-pose proportions match the actual subject. Bone\n  *direction* is preserved (changing it disrupts the T-pose look the BVH file\n  was authored with).\n\n### Multi-person export\n\nMultiple skeletons in the same scene are exported as **separate BVH files**, one\nper tracked identity. Identity persistence is handled by a built-in\nbbox-IoU greedy tracker:\n\n* IoU threshold `0.10`; tracks are retired after `90` frames missing (≈ 3 s at\n  30 fps).\n* Detections with degenerate bboxes (anchored at `(0, 0)` or near-zero area)\n  are dropped before they hit the tracker — these are common YOLO failure\n  modes that otherwise would spawn spurious tracks.\n* While a track is alive but missing this frame, its previous pose is\n  duplicated so the BVH timeline stays continuous through brief occlusions.\n\nFilenames are derived from `--bvh PATH`:\n\n| `--bvh` value | Outputs                              |\n|---------------|--------------------------------------|\n| `p.bvh`       | `p_0.bvh`, `p_1.bvh`, …              |\n| `out\u002Frun`     | `out\u002Frun_0.bvh`, `out\u002Frun_1.bvh`, …  |\n| `cap.mocap`   | `cap_0.mocap`, `cap_1.mocap`, …      |\n\nEach file is fully independent — drop into Blender \u002F BVHTester \u002F any DCC.\n\n### Validating the output\n\n```bash\n# Render a 3D-keypoints CSV at the same time, then compare hip-relative\n# joint positions between the BVH and MHR's own 3D keypoints.\n.\u002Ffast_sam_3dbody_run --from boom.mp4 \\\n    --bvh .\u002Fp.bvh --out \u002Ftmp\u002Fboom_mhr.csv --headless\n\nsource venv\u002Fbin\u002Factivate\npython3 scripts\u002Fverify_bvh_motion.py .\u002Fp_0.bvh \u002Ftmp\u002Fboom_mhr.csv\n```\n\nA clean run prints per-joint median \u002F p90 \u002F max error in cm; numbers around\n2–5 cm on trunk joints and 5–15 cm on extremities are the expected range\n(the larger residual on hands\u002Ffeet partly reflects MHR's 70-keypoint surface\nlandmarks not coinciding with the LBS rotation-centre joints).\n\n### How the mapping is built\n\nThe MHR body model uses 127 named joints (`body_world`, `root`, `l_uparm`,\n`r_thumb1`, …) — names that don't appear in `body_model.lbs` but are exported\nfrom the JIT model:\n\n```bash\n# (Re)generate src\u002Fmhr_joint_table.h from a checkpoint\nsource venv\u002Fbin\u002Factivate\npython3 scripts\u002Fbuild_joint_table.py\n# pass MHR_MODEL_PT=\u002Fpath\u002Fto\u002Fmhr_model.pt to override the default location\n```\n\n`bvh_writer.cpp` then matches each BVH joint name to an MHR name via the\nhand-authored `NAME_MAP` table. To support a new BVH template just add entries\nto that table (and rebuild).\n\n### Implementation notes\n\n* The BVH I\u002FO comes from a vendored, trimmed-down copy of\n  [`MotionCaptureLoader`](https:\u002F\u002Fgithub.com\u002FAmmarkoV\u002FRGBDAcquisition\u002Ftree\u002Fmaster\u002Fopengl_acquisition_shared_library\u002Fopengl_depth_and_color_renderer\u002Fsrc\u002FLibrary\u002FMotionCaptureLoader)\n  in `GraphicsEngine\u002FMotionCaptureLoader\u002F` (plus `TrajectoryParser\u002FInputParser_C`).\n  We use `bvh_loadBVH` for parsing the template hierarchy and `dumpBVHToBVH` for\n  serialising the result.\n* The per-person motion buffer lives in `std::vector\u003Cfloat>` and is transplanted\n  into `mc->motionValues` at close-time, then detached before `bvh_free()` so\n  the library doesn't try to free our std::vector storage.\n* If you only have one person in the scene you'll get exactly one file\n  (`\u003Cname>_0.bvh`) — there is no single-file mode for backwards compatibility.\n\n### Driving a MakeHuman model in Blender\n\n`blender\u002Fblender_bvh_plugin.py` is a Blender add-on (by [AmmarkoV](https:\u002F\u002Fgithub.com\u002FAmmarkoV)) that\nplays one of these BVHs onto a MakeHuman-rigged character via the\n[**mpfb \u002F MakeHuman plugin for Blender**](http:\u002F\u002Fstatic.makehumancommunity.org\u002Fmpfb.html). It maps\nthe BVH joints onto the MakeHuman armature with copy-rotation bone constraints\n(body \u002F hands \u002F feet \u002F face are independently selectable), and exposes a\n**\"MocapNET BVH Animation Helper\"** panel in the 3D viewport's N-panel.\n\nEnd-to-end workflow:\n\n```bash\n# 1) Generate one BVH per detected person\n.\u002Ffast_sam_3dbody_run --from clip.mp4 --bvh .\u002Fp.bvh --headless\n# → p_0.bvh, p_1.bvh, …\n\n# 2) (One-time) install a known-good Blender + open the plugin\ncd blender && .\u002FdownloadAndInstallBlender.sh\n# downloads blender-3.4.1, launches it with the plugin loaded;\n# on first run the plugin will offer to fetch + install the mpfb2 MakeHuman addon\n```\n\nInside Blender:\n\n1. Use the **MakeHuman** (mpfb) tab to create or load a skinned character.\n2. `File → Import → Motion Capture (.bvh)` and pick one of the `p_\u003Cid>.bvh` files.\n   The BVH skeleton appears as a separate armature.\n3. Open the **MocapNET BVH Animation Helper** panel, point *Source BVH* at the\n   imported armature, tick the body parts you want driven (body \u002F hands \u002F\n   feet \u002F face) and click **Apply** — the plugin adds copy-rotation constraints\n   on every matching MakeHuman bone.\n4. Scrub or render the timeline as usual; the character now follows the\n   exported motion.\n\nThe plugin auto-handles naming variants between the BVH skeleton (`body.bvh`,\nwhich is what we export against) and the MakeHuman armature, so the\n`p_\u003Cid>.bvh` files coming out of `--bvh` work without any further renaming.\n\n---\n\n## C++ library API\n\n```cpp\n#include \"fast_sam_3dbody.h\"\n\nfsb::PipelineConfig cfg;\ncfg.onnx_dir        = \".\u002Fonnx\";\ncfg.gguf_path       = \".\u002Fonnx\u002Fpipeline.gguf\";\ncfg.yolo_path       = \".\u002Fonnx\u002Fyolo.onnx\";\ncfg.cuda_device     = 0;       \u002F\u002F -1 = CPU only\ncfg.skip_body_model = true;    \u002F\u002F faster: no vertices\ncfg.max_persons     = 4;       \u002F\u002F 0 = unlimited\n\nfsb::Pipeline pipeline;\npipeline.load(cfg);\n\n\u002F\u002F BGR uint8 pointer, width, height\nstd::vector\u003Cfsb::MHRResult> results =\n    pipeline.process_bgr(bgr_ptr, width, height);\n\nfor (const auto& r : results) {\n    \u002F\u002F r.bbox          [4]   x1 y1 x2 y2 (original image pixels)\n    \u002F\u002F r.global_rot    [3]   Euler ZYX global orientation\n    \u002F\u002F r.body_pose     [133] joint angles\n    \u002F\u002F r.shape         [45]  identity betas\n    \u002F\u002F r.pred_cam_t    [3]   raw camera head: [s, tx, ty]\n    \u002F\u002F r.focal_length        estimated focal length (pixels)\n    \u002F\u002F r.keypoints_yolo[51]  COCO 17 × [x,y,conf]\n    \u002F\u002F r.pred_vertices [18439*3]  (empty when skip_body_model=true)\n}\n\npipeline.free();\n```\n\n## Plain C \u002F ctypes API\n\n```c\n#include \"fast_sam_3dbody_capi.h\"\n\nFsbHandle h = fsb_create();\n\nFsbConfig cfg = {\n    .onnx_dir        = \".\u002Fonnx\",\n    .gguf_path       = \".\u002Fonnx\u002Fpipeline.gguf\",\n    .yolo_path       = \".\u002Fonnx\u002Fyolo.onnx\",\n    .cuda_device     = 0,\n    .skip_body_model = 1,\n    .person_thresh   = 0.5f,\n    .person_nms_iou  = 0.45f,\n    .max_persons     = 0,\n};\nfsb_load(h, &cfg);\n\nFsbResult results[32];\nint n = fsb_process_bgr(h, bgr, width, height, results, 32);\n\nfor (int i = 0; i \u003C n; i++) {\n    \u002F\u002F results[i].bbox, .body_pose, .yolo_kps, ...\n}\n\nfsb_destroy(h);\n```\n\n---\n\n## Performance notes\n\n| Stage | Time (RTX 3090, B=1) |\n|-------|----------------------|\n| YOLO detection | ~5 ms |\n| Backbone (DINOv3-ViT-H) | ~150–200 ms |\n| Decoder (6-layer) | ~20 ms |\n| MHR + camera FFN (CPU) | \u003C1 ms |\n| Native C LBS (optional) | \u003C1 ms |\n\n- Backbone is the bottleneck; it dominates end-to-end latency.\n- Use `--skip-body` unless 3D vertices are required.\n- For higher throughput, batch multiple crops in a single backbone forward pass (already done when multiple persons are detected).\n\n\n\n---\n\nThe official PyTorch SAM 3D Body repository from Meta Superintelligence Labs is :\n\nhttps:\u002F\u002Fgithub.com\u002Ffacebookresearch\u002Fsam-3d-body\n\n---\n\n## Citation\n\nIf you use this software repository in your research or work, please cite:\n\n```bibtex\n@misc{qammaz2026sam3dbodycpp,\n  author       = {Qammaz, Ammar},\n  title        = {{SAM3DBody-cpp}: Standalone {C++} Inference Engine for {SAM-3D-Body}},\n  year         = {2026},\n  howpublished = {\\url{https:\u002F\u002Fgithub.com\u002FAmmarkoV\u002FSAM3DBody-cpp}},\n  note         = {Zero-dependency runtime: ONNX Runtime + ggml, with BVH export and Python ctypes frontends}\n}\n```\n\nas well as the Meta AI team behind the awesome paper that proposes the SAM 3D Body method.\n\n```bibtex\n@article{yang2026sam3dbody,\n  title={SAM 3D Body: Robust Full-Body Human Mesh Recovery},\n  author={Yang, Xitong and Kukreja, Devansh and Pinkus, Don and Sagar, Anushka and Fan, Taosha and Park, Jinhyung and Shin, Soyong and Cao, Jinkun and Liu, Jiawei and Ugrinovic, Nicolas and Feiszli, Matt and Malik, Jitendra and Dollar, Piotr and Kitani, Kris},\n  journal={arXiv preprint arXiv:2602.15989},\n  year={2026}\n}\n```\n\n","SAM3DBody-cpp 是一个从单个摄像头实时重建三维全身模型的项目，支持多人BVH输出。该项目使用纯C++运行时环境，结合ONNX和ggml技术，能够生成包含70个关节（含手部）的骨架模型。它可以从BGR图像中提取每个人的MHR身体姿态参数、相机位移，并可选地生成完整的3D网格顶点。此外，还提供了Python前端接口通过ctypes调用编译后的共享库以及CSV导出功能。适用于需要进行实时或离线人体动作捕捉与分析的场景，如虚拟现实、动画制作等领域。",2,"2026-06-11 03:57:25","CREATED_QUERY"]