This Github presents the code for the following paper: "Pose-independent 3D Anthropometry from Sparse Data" presented at ECCV 2024 workshop "T-CAP 2024 Towards a Complete Analysis of People".
TL;DR : Estimate 11 body measurements from 70 body landmarks of a posed subject.
You can use π³ docker to facilitate running the code. After cloning the repo, run in terminal:
cd docker
sh build.sh
sh docker_run.sh CODE_PATH DATA_PATH
by adjusting the CODE_PATH
to the cloned pose-independent-anthropometry
directory and DATA_PATH
to the data directory you want to access in the docker container. This creates a pose-independent-anthropometry-container
which you can attach to by running:
docker exec -it pose-independent-anthropometry-container /bin/bash
π§ If you do not want to use docker, you can install the docker/requirements.txt
into your own environment. π§
Download:
SMPL_{SEX}.pkl
(MALE, FEMALE and NEUTRAL) models into the data/body_models/smpl
foldersmpl_train_poses.npz
and smpl_val_poses.npz
from here and put them in the folder data/poses
gmm_08.pkl
file from here and put it in the data/prior
folder.Finally, initialize the smpl-anthropometry submodule by running:
git submodule update --init --recursive
The datasets used in the paper are either based on CAESAR, DYNA or 4DHumanOutfit:
Once you obtain all of the datasets, we provide scripts to create all of the dataset versions used in the paper.
The dataset structure assumed is the following:
{path/to/CAESAR}/Data AE2000/{country}/PLY and LND {country}/
which contains scans in .ply.gz
format and landmarks in .lnd
format, and country
can be any of the following: Italy, North America or The Netherlands.
You also need the SMPL fittings to the scans (both the parameter fittings and the vertex fittings) in format
{path/to/fitting}/{subject_name}.npz
To create the fittings in this format you use the SMPL-Fitting repository and run:
python fit_body_model.py onto_dataset --dataset_name CAESAR
python fit_vertices.py onto_dataset --dataset_name CAESAR --start_from_previous_results <path-to-previously-fitted-bm-results>
where <path-to-previously-fitted-bm-results>
is the path to the fitted SMPL body model from the first line of code.
Finally, adjust the following paths in configs/config_real.yaml
:
caesar_dir
: path to the CAESAR datasetfitted_bm_dir
: path to the fitted parameters to the CAESAR dataset obtained from the SMPL-Fitting repositoryfitted_nrd_dir
: path to the fitted vertices to the CAESAR dataset obtained from the SMPL-Fitting repositoryTo create the training dataset, first complete the steps from CAESAR preprocessing. Then, you need to create the poses used for training by running:
python dataset.py cluster_dataset
cd scripts
python create_training_poses.py --fitted_bm_dir <path/to/fitted/SMPL/to/CAESAR>
where fitted_bm_dir
is the path to the fitted SMPL body model to the CAESAR scans (see CAESAR preprocessing)
Finally, you can create the training data using:
cd scripts
python create_CAESAR_POSED_train_dataset.py --save_to <path/to/save/the/dataset/to>
where save_to
is the path where you want to save the created dataset to.
To create the validation dataset, first complete the steps from CAESAR preprocessing. Then, you can run:
cd scripts
python create_CAESAR_POSED_val_dataset.py --save_to <path/to/save/the/dataset/to>
where save_to
is the path where you want to save the created dataset to.
To create the dataset, first complete the steps from CAESAR preprocessing. Then, you can run:
cd scripts
python create_CAESAR_APOSE_test_dataset.py --save_to <path/to/save/the/dataset/to>
where save_to
is the path where you want to save the created dataset to.
To create the dataset, first complete the steps from CAESAR preprocessing.
Since the noise is added randomly, we provide the vector displacements from the original landmarks in data/processed_datasets/dataset_test_unposed_noisy_displacements
. To obtain the noisy landmarks you need to add the displacements to the original landmarks provided in the CAESAR dataset as:
ceasar_noisy_landmarks = caesar_landmarks + displacement_vector
If you, however, want to create your own noisy dataset, you can run:
cd scripts
python create_CAESAR_NOISY_test_dataset.py --save_to <path/to/save/the/dataset/to>
where save_to
is the path where you want to save the created dataset to.
Because the sitting B-pose in CAESAR does not have all of the landmarks necessary to run our method, we transfer the missing landmarks using the fitted SMPL body model. To transfer the landmarks, run:
cd annotate
python annotate_CAESAR_landmarks.py --caesar_path <path/to/CAESAR> --fitting_path <path/to/fitted/SMPL/to/scans> --save_to <path/to/save/the/landmarks/to>
cd ..
Then, you can create the dataset with:
cd scripts
python create_CAESAR_SITTING_test_dataset.py --save_to <path/to/save/the/dataset/to> --transferred_landmark_path <path/to/transferred/landmarks>
where save_to
is the path where you want to save the created dataset to and transferred_landmark_path
is the path where you saved the transferred landmarks from the code above.
To create the dataset, first complete the steps from CAESAR preprocessing. Then, you can run:
cd scripts
python create_CAESAR_POSED_test_dataset.py --save_to <path/to/save/the/dataset/to>
where save_to
is the path where you want to save the created dataset to.
Download the dataset from here (you will need to sign up).
You only need the dyna_male.h5
and dyna_female.h5
files.
The dataset structure assumed is the following:
{path/to/4DHumanOutfit}/{subject_name}/{subject_name}-{clothing_type}-{action}/*/model-*.obj
After you get the dataset, you can use:
cd scripts
bash unzip_4DHumanOutfit_scans.sh <path/to/4DHumanOutfit> <unzip/destination/path>
to unzip the dataset, where <unzip/destination/path>
is the folder where you want to unzip it.
The following subjects are used:
ben
leo
mat
kim
mia
sue
in tight clothing, performing the following actions:
dance
run
avoid
The scans provided by 4DHumanOutfit are the ones with resolution OBJ_4DCVT_15k
.
The dataset also comes with the fitted SMPL parameters (upon request) using the approach from [3], in the same format as the provided scans:
{path/to/fittings}/{subject_name}/{subject_name}-{clothing_type}-{action}/{parameter}.pt
where {parameter}
is any of the follwing: betas.pt
,poses.pt
and trans.pt
.
Finally, you can obtain the landmarks by running:
cd annotate
python annotate_4DHumanOutfit_landmarks.py --scan_paths <path/to/4DHumanOutfit> --fit_paths <path/to/fittings> --transfer_method simple
where
scan_paths
is the path to the downloaded and unzipped dataset
fit_paths
is the path to the SMPL parameters
transfer_method
is the way of obtaning the landmarks and can be one of the following:
simple
where the transferred landmarks correspond to the actual SMPL landmarksnn
where the transferred landmarks correspond to the nearest neighbor of each fitted SMPL landmark and the scannn_threshold
where the transferred landmark is the nearest neighbor of the fitted SMPL landmark to the scan if the distance is below the nn_threshold
(defined below), else it is the actual SMPL landmarknn_threshold
is the nearest neighbor threshold in meters for the nn_threshold transfer method
The landmarks will be saved in the same folder as the parameters fit_paths
and the transfer_method
used in the paper is the simple
one.
To train our model you can run:
python train.py
To visualize the loss curves during training run in a seperate terminal:
visdom -p <port>
and navigate in your browser to http://localhost:<port>/
. If you do not see any curves, make sure you choose the lm2meas
environment in the dropdown menu and make sure the port you choose is the same one as in configs/config_real.yaml
under visualization/port
.
The training parameters are set in configs/config_real.yaml
. To train the same model as in our paper, you can leave all the parameters as they are except potentially fixing the paths defined throught the configuration file. We briefly explain all the parameters for easier reference:
general parameters:
continue_experiment
: (str) name of the experiment in format "%Y%m%d%H%M_%S" from the results folder you wish to continue runningexperiment_name
: (str) name your experiment for easier referencevisualization parameters:
display
: (bool) visualize loss curves with visdom or notport
: (int) the loss curves will be visualized on http://localhost:<port>/
env
: (str) visdom environment of the experimentlearning parameters:
model_name
: (str) name of the model to train, defined in models.py
dataset_name
: (str) name of the dataset to use defined in dataset.py
- actual data used is defined in dataset_configs
belowsave_model
: (bool) save trained model or notwhat_to_return
: (list) list of variables the dataset will return to the training script (depends on the dataset used)transform_landmarks
: (list) of feature transformers defined in feature_transformers
below - they transform the input data for the modellandmark_normalization
: (str) of how to normalize the landmarks (only pelvis
is acceptable)batch_size
: (int) model batch sizen_workers
: (int) number of pytorch workers to load the batchesnepoch
: (int) number of training epochs to runinit_lr
: (float) initial value of the learning ratelrate_update_func
: (str) learning rate scheduler defined in learning_rate_schedulers
belowmeasurements
: (list) of measurements to train the model onlandmarks
: (dict) of landmarks defined on the SMPL body model (dict keys are used)seed
: (int) training random seedweight_init_option
: (str) initialization of the model weights defined in weight_init_options
belowpaths parameters:
save_path_root
: (str) where to save the training resultscaesar_dir
: (str) path to the CAESAR datasetfitted_bm_dir
: (str) path to the SMPL fitted body models (see CAESAR preprocessing)fitted_nrd_dir
: (str) path to the SMPL fitted vertices (see CAESAR preprocessing)body_models_path
: (str) path to the SMPL body models (see Getting started)pose_prior_path
: (str) path to the pose prior from [2]preprocessed_path
: (str) path to the preprocessed files used to unpose and repose the CAESAR scans in the OnTheFlyCAESAR datasetmoyo_poses_path
: (str) path to the MOYO datasetcaesar_gender_mapper
: (str) path to the CAESAR gender mapper file which maps a subject name to their provided sexmodel_configs parameters:
SimpleMLP
: setup the layer dimensions for the SimpleMLP modeldataset_configs parameters:
NPZDataset
: setup the train and validation paths for the datasets you created in π» Datasetsfeature_transformers parameters:
coords
: returns the input landmarks and ravels into a single dimension vector if requireddistances_all
: returns the distances between all the input landmarksdistances_grouped
: returns the distances between the desired landmarks defined in the path grouping_inds_path
learning_rate_schedulers parameters:
ConstantLR
: keeps a constant learning rate defined in init_lr
weight_init_options parameters:
output_layer_bias_to_mean_measurement
: initialize the output layer of the SimpleMLP to the mean training set measurementsNote that many of the parameters are not necessary to successfully train the model.
You can use evaluate.py
to reproduce the results from the paper. We provide our trained model in results/2024_07_11_09_42_48
.
The dataset_path
input variable to the evaluate.py
script should correspond to the paths of the datasets you created in π» Datasets. If you used our default paths, then you can omit it in the following calls.
python evaluate.py CAESAR_STAND -R results/2024_07_11_09_42_48 --dataset_path <path/to/dataset>
python evaluate.py CAESAR_NOISY -R results/2024_07_11_09_42_48 --pelvis_normalization --dataset_path <path/to/dataset>
python evaluate.py CAESAR_SIT_TRANS_BM -R results/2024_07_11_09_42_48 --dataset_path <path/to/dataset>
python evaluate.py CAESAR_POSED -R results/2024_07_11_09_42_48 --dataset_path <path/to/dataset>
python evaluate.py DYNA_POSED -R results/2024_07_11_09_42_48 --dataset_path <path/to/dataset> --pelvis_normalization
python evaluate.py 4DHumanOutfit -R results/2024_07_11_09_42_48 --pelvis_normalization --parameters_path <path/to/params>
where parameters_path
is the path to the SMPL parameters fitted to the scans along with the obtained landmarks from π» Datasets.
In order to evaluate the baseline models described in the paper on a given dataset, first you need to fit the SMPL body model onto the provided landmarks by running:
cd scripts
python add_shape_to_dataset.py --dataset_path <path/to/dataset>
after which you can evaluate it with:
python evaluate_baseline.py --dataset_path <path/to/evaluation/dataset>
To run the method from [4], you can clone their repository Landmarks2Anthropometry and switch to the eccv24 branch where the authors provide the scripts to run their method on the datasets from the paper. The datasets are set with the variable dataset_path
and correspond to the ones created in π» Datasets.
To evaluate on the CAESAR A-pose, run:
python eccv_stand.py --dataset_path <path/to/CAESAR/Apose/dataset>
To evaluate on the CAESAR A-pose with noisy landmarks, run:
python eccv_noisy.py --dataset_path <path/to/CAESAR/Apose/noisy/dataset>
To evaluate on the CAESAR sitting B-pose, run:
python eccv_sit.py --dataset_path <path/to/CAESAR/Bpose/dataset>
To evaluate on the CAESAR arbitrary pose, run:
python eccv_posed.py --dataset_path <path/to/CAESAR/posed/dataset>
The subjects we use for training, validation and testing are the same ones as used in [1], excluding the ones that have missing landmarks or measurements. See paper for more details.
We provide the latex tables from the paper so you can easily compare with our model:
latex_tables/caesar-standing-male-results.tex
latex_tables/caesar-standing-female-results.tex
latex_tables/caesar-sit-results.tex
latex_tables/caesar-posed-results.tex
latex_tables/dyna-results.tex
latex_tables/four-d-human-outfit-results.tex
We already provide the pose-invariant features in data/landmarks2features/lm2features_distances_grouped_from_SMPL_INDEX_LANDAMRKS_REVISED_inds_removed_inds_with_median_dist_bigger_than_one.npy
.
To recreate these features or create others, you can run:
cd scripts
python find_pose_invariant_landmark_features.py --caesar_dir <path/to/caesar/dataset>
To create Figure 4 from the paper you can run:
cd scripts
python find_landmark_measurements_ambiguity.py
which will create a figure named ambiguity_max_landmarks_wrt_measurements.pdf
.
To find out the average displacement of each landmark in the Noisy CAESAR dataset run:
python compute_stats.py NoisyCaesar
To find out how many and which landmarks are missing in the original CAESAR sitting dataset, run:
python compute_stats.py CAESAR_SITTING
Parts of the code are inspired from smplify-x and 3D-CODED. We thank the authors for providing the code.
[1] Tsoli et al.: "Model-based Anthropometry: Predicting Measurements from 3D Human Scans in Multiple Poses"
[2] Pavlakos et al.: "Expressive Body Capture: 3D Hands, Face, and Body from a Single Image"
[3] Marsot et al.: "Representing motion as a sequence of latent primitives, a flexible approach for human motion modelling"
[4] BojaniΔ et al.: "Direct 3D Body Measurement Estimation from Sparse Landmarks"