File size: 9,191 Bytes
43bb4c3 d6c8140 43bb4c3 d6c8140 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | ---
license: other
license_name: dinov3-license
license_link: https://huggingface.co/BodenAI/EgoRayFormer/blob/main/LICENSE_DINOv3.md
library_name: pytorch
pipeline_tag: keypoint-detection
base_model: timm/vit_small_plus_patch16_dinov3.lvd1689m
tags:
- egocentric
- 3d-human-pose-estimation
- human-pose-estimation
- stereo
- fisheye
- pytorch-lightning
metrics:
- mpjpe
- pa-mpjpe
model-index:
- name: egorayformer_ue2.ckpt
results:
- task:
type: keypoint-detection
name: Egocentric 3D human pose estimation
dataset:
type: unrealego2
name: UnrealEgo2
split: test
metrics:
- type: mpjpe
name: MPJPE (mm)
value: 17.53
- type: pa-mpjpe
name: PA-MPJPE (mm)
value: 16.8
- name: egorayformer_rw.ckpt
results:
- task:
type: keypoint-detection
name: Egocentric 3D human pose estimation
dataset:
type: unrealego-rw
name: UnrealEgo-RW
split: test
metrics:
- type: mpjpe
name: MPJPE (mm)
value: 49.34
- type: pa-mpjpe
name: PA-MPJPE (mm)
value: 40.59
- name: egorayformer_ue2_to_rw.ckpt
results:
- task:
type: keypoint-detection
name: Egocentric 3D human pose estimation
dataset:
type: unrealego-rw
name: UnrealEgo-RW
split: test
metrics:
- type: mpjpe
name: MPJPE (mm)
value: 47.68
- type: pa-mpjpe
name: PA-MPJPE (mm)
value: 37.73
---
<p align="center">
<img src="https://raw.githubusercontent.com/BodenAI/EgoRayFormer/main/docs/logo/en_logo.png" alt="BODENAI" width="220">
</p>
<h1 align="center">EgoRayFormer</h1>
<p align="center"><b>EgoRayFormer: Ray-Space Stereo Refinement for Egocentric 3D Human Pose Estimation</b></p>
<p align="center">
<a href="https://arxiv.org/abs/2610.26641">Paper</a> ·
<a href="https://github.com/BodenAI/EgoRayFormer">Code</a>
</p>
<p align="center">Haozhe Wang, Songyuan Wu, Jihai Xu, Jie Zhao · Boden AI</p>
<p align="center"><b>Built with DINOv3</b></p>
This repository holds the checkpoints of [EgoRayFormer](https://arxiv.org/abs/2610.26641), a causal 3D human pose
estimator for head-mounted stereo fisheye cameras. For each joint, the decoder projects shared 3D hypotheses along and
around its viewing ray into both images. A geometric branch then corrects the projected joint locations and intersects
the resulting rays, and a learned gate blends this geometric estimate with a learned pose update. Code, training and
evaluation: [github.com/BodenAI/EgoRayFormer](https://github.com/BodenAI/EgoRayFormer).

## Checkpoints
Three models of Table 1 of the paper, all with a DINOv3 ViT-S+/16 encoder at 384 × 384 (35.1 M parameters in total). Each file
contains the EMA weights used for evaluation (approximately 134 MiB per checkpoint).
| File | Training data | Test set | Config |
|---|---|---|---|
| [`egorayformer_ue2.ckpt`](https://huggingface.co/BodenAI/EgoRayFormer/resolve/main/egorayformer_ue2.ckpt) | UnrealEgo2 | UnrealEgo2 | [`configs/egorayformer_ue2.yaml`](https://github.com/BodenAI/EgoRayFormer/blob/main/configs/egorayformer_ue2.yaml) |
| [`egorayformer_rw.ckpt`](https://huggingface.co/BodenAI/EgoRayFormer/resolve/main/egorayformer_rw.ckpt) | UnrealEgo-RW | UnrealEgo-RW | [`configs/egorayformer_rw.yaml`](https://github.com/BodenAI/EgoRayFormer/blob/main/configs/egorayformer_rw.yaml) |
| [`egorayformer_ue2_to_rw.ckpt`](https://huggingface.co/BodenAI/EgoRayFormer/resolve/main/egorayformer_ue2_to_rw.ckpt) | UnrealEgo2, then UnrealEgo-RW | UnrealEgo-RW | [`configs/egorayformer_ue2_to_rw.yaml`](https://github.com/BodenAI/EgoRayFormer/blob/main/configs/egorayformer_ue2_to_rw.yaml) |
SHA-256:
```
f4a0028421d3b9a1d8bb45fe3d336e072d8036a59afc4841fb03c5d7ce9c5100 egorayformer_ue2.ckpt
5b4612438b6204bab198f9e9d1cc7e696cd919052bc48c5cd084676e932f4c08 egorayformer_rw.ckpt
dfeb9c2867e14f4df97cda35f8fbffa37ba34f003e5a3b4133753a73ce12856e egorayformer_ue2_to_rw.ckpt
```
## Results
Device-relative protocol on the official test splits, mm. Every sequence is processed as one causal stream in FP32.
The released files are the seed-42 models; the paper reports the mean ± s.d. over seeds 42, 1 and 2.
| Model | Test set | MPJPE (this checkpoint) | PA-MPJPE (this checkpoint) | MPJPE (paper, 3 seeds) | PA-MPJPE (paper, 3 seeds) |
|---|---|---|---|---|---|
| `egorayformer_ue2` | UnrealEgo2 | 17.53 | 16.80 | 17.64 ± 0.12 | 16.86 ± 0.08 |
| `egorayformer_rw` | UnrealEgo-RW | 49.34 | 40.59 | 49.55 ± 0.40 | 40.59 ± 0.30 |
| `egorayformer_ue2_to_rw` | UnrealEgo-RW | 47.68 | 37.73 | 47.57 ± 0.34 | 37.21 ± 0.46 |
See the paper for the comparison with other methods.
## Usage
The checkpoints are used with the code repository. Install it, prepare the UnrealEgo2 / UnrealEgo-RW records with the
scripts of the repository (see its README), then download a checkpoint and evaluate it:
```bash
git clone https://github.com/BodenAI/EgoRayFormer.git && cd EgoRayFormer
pip install torch==2.4.0 torchvision==0.19.0 --index-url https://download.pytorch.org/whl/cu121
pip install -e .
mkdir -p checkpoints
for m in egorayformer_ue2 egorayformer_rw egorayformer_ue2_to_rw; do
wget -P checkpoints https://huggingface.co/BodenAI/EgoRayFormer/resolve/main/$m.ckpt
done
python run.py validate --config configs/egorayformer_rw.yaml --config configs/eval.yaml \
--model.model.encoder.pretrained false --data.root /data/unrealego/processed \
--ckpt_path checkpoints/egorayformer_rw.ckpt
```
Use `egorayformer_ue2` or `egorayformer_ue2_to_rw` for the other two models. For the test split, run
`EGORAYFORMER_ALLOW_TEST=1 python run.py test` with the same arguments. `--model.model.encoder.pretrained false` skips
the download of the DINOv3 weights, which come from the checkpoint.
**Input.** Stereo fisheye video from a head-mounted rig: the left and right images of each frame (resized to
384 × 384) and the calibration of the rig (fisheye camera models and camera-from-device extrinsics). The model projects
3D hypotheses into both images, so the calibration is part of the input. It processes frames causally and keeps a
streaming state (key–value caches, trajectory history, previous pose).
**Output.** The 3D positions of 16 joints (UnrealEgo skeleton: head, neck, upper arms, lower arms, hands, thighs,
calves, feet, balls of the feet) relative to the device, for every frame.
## Training
Each model is trained in two stages on one NVIDIA H200 GPU:
1. 2D heatmap pre-training of the encoder at 256 × 256, starting from the DINOv3 ViT-S+/16 weights
(`timm/vit_small_plus_patch16_dinov3.lvd1689m`);
2. end-to-end training on clips of 8 consecutive frames at 384 × 384, batch size 16, AdamW, bf16 mixed precision:
12 epochs on UnrealEgo-RW, 3 epochs on UnrealEgo2. The UnrealEgo2 → UnrealEgo-RW model starts from the weights of the
UnrealEgo2 model and is trained for 12 epochs on UnrealEgo-RW.
The checkpoint with the lowest validation MPJPE is selected. The commands are in the README of the code repository.
**Data.** [UnrealEgo2 and UnrealEgo-RW](https://unrealego.mpi-inf.mpg.de/) (Akada et al., CVPR 2024), official splits.
UnrealEgo2 is rendered with a synthetic stereo fisheye rig; UnrealEgo-RW was captured with a physical head-mounted rig.
For UnrealEgo-RW, the camera-from-device transform of every capture session is fitted to the training annotations only.
## Limitations
- The models were trained and evaluated on the two rigs of UnrealEgo2 and UnrealEgo-RW only. Other headsets need their
calibration, and accuracy on other rigs has not been evaluated.
- Errors increase with the distance of a joint from the cameras; the lower body has the largest errors.
- One streaming step takes about 43 ms on an NVIDIA H200 (FP32, batch 1, model forward only), so the numbers above do
not establish real-time operation on other hardware.
- The models estimate the pose of the person wearing the headset; they are intended for research.
## License
The checkpoints contain weights derived from DINOv3 and are distributed under the
[DINOv3 License](LICENSE_DINOv3.md). The code is released under the Apache License 2.0 in the
[code repository](https://github.com/BodenAI/EgoRayFormer). UnrealEgo2 and UnrealEgo-RW are distributed by their authors
under their own terms.
## Citation
```bibtex
@article{wang2026egorayformer,
title = {{EgoRayFormer}: Ray-Space Stereo Refinement for Egocentric {3D} Human Pose Estimation},
author = {Wang, Haozhe and Wu, Songyuan and Xu, Jihai and Zhao, Jie},
journal = {arXiv preprint arXiv:2610.26641},
year = {2026}
}
```
## Contact Us
<p align="center">
<img src="https://raw.githubusercontent.com/BodenAI/EgoRayFormer/main/docs/logo/code.jpg" alt="WeChat QR code" width="110">
</p>
<p align="center">
<a href="https://bodenai.com">bodenai.com</a> (中文) ·
<a href="https://www.boden.ai">boden.ai</a> (English)
</p>
<p align="center">
<a href="mailto:company@bodenai.com">company@bodenai.com</a> ·
<a href="mailto:EAI@bodenai.com">EAI@bodenai.com</a>
</p>
|