This repository contains the code and experiments accompanying our paper:
"Discovering Geometric Biases in 3D Face Reconstruction: A Curvature-Aware Spectral Framework for Fairness Evaluation" (ECCV 2026)
This project provides a compact pipeline to:
- extract specific face regions (nose, mouth, cheek and forehead) from reconstructed 3D meshes,
- compute and compare mean-curvature maps between reconstruction and ground truth,
- project curvature-error maps into Laplace-Beltrami spectral basis,
- cluster reconstruction error patterns and inspect demographic correlations.
- Clone the repository
git clone git@github.com:artefactory/face-recon-fairness.git
cd face-recon-fairness- Create and activate your virtual environment
python3 -m venv .venv
source .venv/bin/activate- Install dependencies
pip install -r requirements.txt-
In order to use our evaluation pipeline, you need an access to REALY benchmark. Please sign the Agreement and indicate the usage of REALY benchmark according to their guideline, then you will get the permission to download the data.
-
Unzip the benchmark file and put "REALY_scan_region/", "REALY_image/" and "REALY_HIFI3D_keypoints/" folders into "data/REALY".
-
Use the images in the "REALY_image/" folder to reconstruct 3D meshes with your method(s) and put them into "data/" folder.
Here is a short example of how to calculate curvature-based error maps @nose and cluster them in Laplace-Beltrami spectral space.
from utils.curvature_calculation import calculate_curvature_maps
from utils.spectral_clustering import (
calculate_spectral_decomposition,
cluster_curvature_maps,
)
# Compute curvature maps for a given face region
H_gt, H_rec, H_diff = calculate_curvature_maps(
face_region="nose",
template_name='basel', # 3DMM template that was used for reconstruction
reconstruction_data_path=reconstruction_data_path, # path to 3D meshes reconstructed with your method
save_path=save_path,
n_neighbors=3,
curvature_plot_save=False,
)
# Spectral decomposition
spectral_coefs, evecs = calculate_spectral_decomposition(
diff_error_maps=H_diff,
face_region="nose",
template_name='basel',
n_eig=512,
reconstruction_data_path=reconstruction_data_path,
save_path=save_path,
)
# Spectral clustering
labels = cluster_curvature_maps(
diff_curvature_maps=H_diff,
spectral_coefs=spectral_coefs,
evecs=evecs,
face_region="nose",
template_name='basel',
reconstruction_data_path=reconstruction_data_path,
save_path=save_path,
)-
Ground truth and reconstruction mean curvature maps, differences between them and the respective error cluster labels will be saved to "<save_path>" folder.
-
[Optional] If you put "curvature_plot_save=True", plots of ground truth and reconstruction mean curvature maps and differences between them will be saved to "<save_path>/plots" for a given face region.
Thank you for reviewing our work. If you encounter any issues or need clarification while evaluating the code, please don't hesitate to contact us (our contact information is available in the paper).
If you consider this package or any of its feature useful for your research, consider citing our paper.
@article{shilova2026discovering,
title={Discovering Geometric Biases in 3D Face Reconstruction: A Curvature-Aware Spectral Framework for Fairness Evaluation},
author={Shilova, Veronika and Malherbe, Emmanuel and Palma, Giovanni and Bokaris, Panagiotis-Alexandros and Risser, Laurent and Loubes, Jean-Michel},
journal={arXiv preprint arXiv:2607.07486},
year={2026}
}This project is licensed under the MIT License - see the LICENSE file for details.
