Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6556cfd
inference on the 3DHP dataset
xiu-cs Jun 13, 2026
a8da942
Add test script for 3DHP dataset inference
xiu-cs Jun 13, 2026
2c73d3a
add lib
xiu-cs Jun 13, 2026
fe27349
clean
xiu-cs Jun 13, 2026
dde13f4
Remove unused ground truth input in 3DHP dataset class and simplify d…
xiu-cs Jun 13, 2026
271f180
Remove unused p_mpjpe_action function from eval_cal.py to streamline …
xiu-cs Jun 13, 2026
a5f05df
Remove unused imports and functions from utils.py to clean up the cod…
xiu-cs Jun 13, 2026
68b3594
Refactor test function in infer_3dhp.py to remove unused variable fro…
xiu-cs Jun 13, 2026
172fc0e
Add script to convert MPI-INF-3DHP test annotations to FMPose3D format
xiu-cs Jun 13, 2026
4a06f50
Add README for MPI-INF-3DHP test dataset with setup instructions and …
xiu-cs Jun 13, 2026
85bd8cc
Update GPU ID in test script for 3DHP dataset to use GPU 0
xiu-cs Jun 13, 2026
b9a6525
Add README for MPI-INF-3DHP test evaluation with detailed dataset pre…
xiu-cs Jun 13, 2026
e79043f
Update test script for 3DHP dataset to include model type, weights, a…
xiu-cs Jun 13, 2026
b2e64d2
Enhance infer_3dhp.py by adding model weights path argument and updat…
xiu-cs Jun 13, 2026
ad158c6
Update
xiu-cs Jun 13, 2026
9ef9847
Add .gitignore file for 3DHP test directory to exclude cache, results…
xiu-cs Jun 13, 2026
ef0bd5c
Update .gitignore to include exceptions for 3dhp_test/lib and its Pyt…
xiu-cs Jun 13, 2026
3187437
Fix action error sum update in mpjpe_by_action_p2 to use individual d…
xiu-cs Jun 13, 2026
a3ccb98
Refactor tqdm usage in test function to remove unnecessary argument
xiu-cs Jun 14, 2026
8a344b8
Enhance model loading error handling in load_model_class function
xiu-cs Jun 14, 2026
4a7bd60
Add tests for 3DHP inference module and error calculation
xiu-cs Jun 14, 2026
5e282b9
Update .gitignore to exclude animal dataset and checkpoint directories
xiu-cs Jun 14, 2026
db70555
Add load_model_weights function for improved model loading
xiu-cs Jun 14, 2026
5ae8326
Add tests for handling partial checkpoints and action filtering in 3D…
xiu-cs Jun 14, 2026
7cd0cbb
Refactor define_actions_3dhp function to improve error handling for a…
xiu-cs Jun 14, 2026
c58d8f9
Add help text for actions argument in parse_args function to clarify …
xiu-cs Jun 14, 2026
99e54e2
Add h5py dependency to pyproject.toml for improved data handling
xiu-cs Jun 14, 2026
0a1bdbc
Update parse_args function to accept argv parameter and add help text…
xiu-cs Jun 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ downloads/
eggs/
.eggs/
lib/
!3dhp_test/lib/
!3dhp_test/lib/*.py
lib64/
parts/
sdist/
Expand Down Expand Up @@ -45,9 +47,12 @@ htmlcov/
*.pkl
*.h5
*.ckpt
animals/checkpoint/
animals/dataset/animal3d/
animals/dataset/control_animal3dlatest/

# Excluded directories
pre_trained_models/
demo/predictions/
demo/images/
**/predictions/
**/predictions/
10 changes: 10 additions & 0 deletions 3dhp_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
__pycache__/
*.py[cod]

results/

*.pth
*.pt
*.ckpt

dataset/*.npz
105 changes: 105 additions & 0 deletions 3dhp_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# MPI-INF-3DHP Test Evaluation
Comment thread
xiu-cs marked this conversation as resolved.

This folder contains utilities for evaluating monocular 3D pose lifting models on the MPI-INF-3DHP test set.

## Model and Weights

By default, the 3DHP test uses the packaged human FMPose3D lifting model (`model_type=fmpose3d_humans`) and leaves `model_weights_path` empty so weights are downloaded automatically from Hugging Face Hub.

`test_3dhp.sh` exposes the model and weights near the top of the script:

```bash
model_type="fmpose3d_humans"
model_weights_path=""
model_path=""
```

To use local weights, set `model_weights_path` to your own checkpoint or to the human pretrained weights we provide on [Google Drive](https://drive.google.com/drive/folders/1aRZ6t_6IxSfM1nCTFOUXcYVaOk-5koGA?usp=sharing):

```bash
model_weights_path="${SCRIPT_DIR}/pretrained/fmpose3d_h36m/FMpose3D_pretrained_weights.pth"
```

To use a local model definition instead of the packaged registry model, set `model_path` to a Python file that defines `Model`:

```bash
model_path="${SCRIPT_DIR}/pretrained/fmpose3d_h36m/model_GAMLP.py"
```

When both `model_path` and `model_weights_path` are set, make sure the local model architecture matches the checkpoint.

## Dataset Preparation

`infer_3dhp.py` expects a processed MPI-INF-3DHP test file at:

```bash
3dhp_test/dataset/data_test_3dhp.npz
```

The `.npz` file is not committed to this repository. Generate it from the official MPI-INF-3DHP test set annotations with `dataset/prepare_3dhp_test_npz.py`.

### Get the official dataset

Get MPI-INF-3DHP from the [official dataset website](https://vcai.mpi-inf.mpg.de/3dhp-dataset/) and follow its license and access instructions. The official package includes download scripts under `source/`; read the included `README.txt`, edit `source/conf.ig` as instructed, then run the test-set downloader:

```bash
cd /path/to/mpi_inf_3dhp/source
bash get_testset.sh
```

After the script downloads and extracts the test set, set `${MPI_INF_3DHP_TEST_ROOT}` to the extracted test-set root. It should contain `TS1` through `TS6`:

```text
/path/to/mpi_inf_3dhp/
mpi_inf_3dhp_test_set/
TS1/
annot_data.mat
...
TS2/
annot_data.mat
...
...
TS6/
annot_data.mat
...
```

Verify that `TS1` through `TS6` each contain `annot_data.mat`:

```bash
for subject in TS1 TS2 TS3 TS4 TS5 TS6; do
test -f "${MPI_INF_3DHP_TEST_ROOT}/${subject}/annot_data.mat" \
&& echo "${subject}: ok" \
|| echo "${subject}: missing annot_data.mat"
done
```

### Generate `data_test_3dhp.npz`

Run from the repository root:

```bash
python 3dhp_test/dataset/prepare_3dhp_test_npz.py \
--test-root "${MPI_INF_3DHP_TEST_ROOT}" \
--output 3dhp_test/dataset/data_test_3dhp.npz
```

It reads each `TS*/annot_data.mat` and writes a compressed npz with this schema:

```text
data = {
"TS1": {
"data_2d": annot2,
"data_3d": univ_annot3,
"valid": valid_frame,
},
...
"TS6": ...
}
```

`ThreeDHPTestDataset` then applies the valid-frame mask, maps the 28-joint 3DHP layout to the 17-joint FMPose3D layout, converts 3D from millimeters to meters, root-centers joints 1-16 around joint 0, and normalizes the 2D coordinates.

## Acknowledgement

The MPI-INF-3DHP npz conversion is adapted from the preprocessing workflow in [P-STMO](https://github.com/paTRICK-swk/P-STMO).
70 changes: 70 additions & 0 deletions 3dhp_test/dataset/prepare_3dhp_test_npz.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""
FMPose3D: monocular 3D Pose Estimation via Flow Matching

Official implementation of the paper:
"FMPose3D: monocular 3D Pose Estimation via Flow Matching"
by Ti Wang, Xiaohang Yu, and Mackenzie Weygandt Mathis
Licensed under Apache 2.0
"""

import argparse
from pathlib import Path

import h5py
import numpy as np

Comment thread
xiu-cs marked this conversation as resolved.

DEFAULT_OUTPUT = Path(__file__).resolve().parent / "data_test_3dhp.npz"


def convert_test(test_root, output_path):
test_root = Path(test_root)
output_path = Path(output_path)
data_by_subject = {}

for annot_path in sorted(test_root.glob("TS*/annot_data.mat")):
subject = annot_path.parent.name
print(f"loading {subject}...")

with h5py.File(annot_path, "r") as data:
valid_frame = np.squeeze(data["valid_frame"][()])
data_2d = np.squeeze(data["annot2"][()])
data_3d = np.squeeze(data["univ_annot3"][()])

data_by_subject[subject] = {
"data_2d": data_2d,
"data_3d": data_3d,
"valid": valid_frame,
}

if not data_by_subject:
raise FileNotFoundError(f"No test annot_data.mat files found under {test_root}")

output_path.parent.mkdir(parents=True, exist_ok=True)
np.savez_compressed(output_path, data=data_by_subject)
print(f"saved {output_path}")


def parse_args():
parser = argparse.ArgumentParser(
description="Convert MPI-INF-3DHP test annotations to the FMPose3D 3DHP test npz."
)
parser.add_argument(
"--test-root",
type=Path,
required=True,
help="Path containing TS1..TS6 folders from the official MPI-INF-3DHP test set.",
)
parser.add_argument(
"--output",
type=Path,
default=DEFAULT_OUTPUT,
help="Output npz path consumed by 3dhp_test/infer_3dhp.py.",
)
return parser.parse_args()


if __name__ == "__main__":
args = parse_args()
convert_test(args.test_root, args.output)
Loading
Loading