FaCT-GS: Fast and Scalable CT Reconstruction with Gaussian Splatting
April 27, 2026 · View on GitHub

Paper | Project Page | Data
Introduction
Official repository for our paper titled FaCT-GS: Fast and Scalable CT Reconstruction with Gaussian Splatting.
Related repositories (included in the installation):
Fast Gaussian Splatting CT Rasterizer | Fast Gaussian Splatting Voxelizer | Fused SSIM (2D and 3D) | Fused 3D TV
Installation
You need to have an NVIDIA GPU with CUDA installed (tested with CUDA 12.1).
Create a dedicated Python environment and install the dependencies:
git clone --recurse-submodules https://github.com/PaPieta/fact-gs.git
cd fact-gs
conda env create -f environment.yml
conda activate fact-gs
export GLM_HOME="$(pwd)/fact_gs/submodules/glm"
pip install --no-build-isolation -r submodules.txt
The GLM_HOME variable is necessary to automatically link it to the voxelizer and rasterizer submodules.
:exclamation: Consider using mamba instead of conda for much faster installation. When available, it should be enough to replace the env creation command with mamba env create -f environment.yml
Data -> get it here
The data used in this project is a collection of volumes and projections generated from various publicly available datasets. A major fraction is a copy from the r2_gaussian project. Check the dataset description for information on sources and licensing.
Details on the contents of each data folder
real_datasetandsynthetic_datasetare direct copies from the r2_gaussian project, used in the main performance analysis. Details on the dataset preparation can be found here for the synthetic dataset, and here for the real one.coral_datasetcontains multiple resolutions of the same coral scan, used in the scaling study.init_datasetcontains scan pairs used in the warmstart vs coldstart initialization study.warmstart_datasetcontains lung CT scan pairs used in the warmstart impact study in supplementary material.teaser_figureholds scans used in generating the main teaser figure of the paper.
Running the code
All scripts are parameterized with a Hydra config, located in the config folder. It can be modified directly or when invoking the script.
Both reconstruction and volume fitting expect the r2_gaussian data layout (meta_data.json).
Parameters shared by all training scripts
(overwrite with category.parameter=new_value)
Model:
- num_gaussians - Number of Gaussians the optimization is initialized with
- data_source_path - Path to the source data folder used during optimization
- model_path - Directory where checkpoints, evaluation dumps and exported point clouds are saved
- init_mode - How Gaussians are initialized:
gradient- gaussian locations sampled based on a probability distribution from a gradient of an FDK-reconstructed volumeintensity- above, but using intensities directly and not their gradientsprecomputed/prior- only applicable for reconstruction (see below)
- density_thresh - Minimum voxel density used to discard background voxels during initialization
- density_rescale - Empirical scaling applied to the sampled densities to compensate for multi-Gaussian occlusion
- scale_min / scale_max - Lower and upper scale bounds expressed as a fraction of the target volume, converted to world units at runtime
- eval - When False only the training cameras are loaded from
meta_data.json
Optimization:
- steps - Number of optimization steps to run. One step equals one rasterization/voxelization pass with backward propagation. In CT recon, an
iterationconsists of processing all available projections. For volume fitting, since there is only one volume used,step==iteration - position_lr_init/final/max_steps - Learning rate schedule for Gaussian centers;
*_max_stepsis expressed as a fraction ofsteps - density_lr_init/final/max_steps - Learning rate schedule for Gaussian densities/opacity
- scaling_lr_init/final/max_steps - Learning rate schedule for per-axis scales
- rotation_lr_init/final/max_steps - Learning rate schedule for spherical harmonics rotations
- lambda_dssim - Weight of the DSSIM loss component (set to 0 to disable)
- lambda_tv - Weight of the 3D total-variation regularizer
- ssim3d_early_stop / ssim3d_early_stop_threshold - Optional early-stopping guard. When enabled, training exits as soon as the reported 3D SSIM reaches or exceeds the provided threshold. Useful for time-to-SSIM studies (defaults to disabled).
- training_time_limit_seconds - Optional wall-clock limit (seconds). When >0, stops training once the accumulated training time crosses the threshold.
- densify_gaussians - Enables/disables periodic Gaussian densification and pruning
- density_min_threshold - Minimum density allowed during pruning; Gaussians below the threshold get removed
- densification_interval/densify_from_step/densify_until_step_percent - Controls when densification starts, how often it is triggered, and up to what portion of training it remains active
- densify_grad_threshold - Gradient magnitude threshold a Gaussian must exceed to be duplicated during densification
- densify_scale_threshold - Largest acceptable Gaussian scale (in % of the volume size) before it gets split during densification
- max_screen_size / max_scale / max_num_gaussians - Optional guards that clamp 2D footprint, 3D scale, or total Gaussian count;
max_num_gaussiansis a multiplier of the initialnum_gaussians(default1.1= 110%)
Evaluation:
- eval_in_training - Run quantitative evaluation in the middle of training
- every_n_steps - Evaluation frequency measured in optimization steps (ignored when
eval_in_training=False) - eval_start - If True, evaluate the initialization before any optimization step
- eval_end - If True, evaluate after the final step (used for leaderboard metrics)
- extra_eval_iter_num - (optional) specific iteration to force an additional evaluation and metric export; useful for catching early progress snapshots such as the 150-iteration dumps used in the paper (
eval_default_extra_150). For reconstruction runs, iterations equal full sweeps over the training cameras, while for volume fittingiteration == step. - visualize_at_eval - When enabled, dumps reconstructed volumes (tiff + preview) at evaluation checkpoints
- visualize_gaussians - Exports Gaussian position/footprint visualizations and error maps for debugging
Profiling:
- profile - Turns PyTorch's profiler on/off
- profile_wait - How many steps to wait before collecting a trace
- profile_active - Number of active steps that are recorded in the trace
Some more details on using Hydra
Parameters can either be changed directly in the config folder or when invoking the script.
To change a specific parameter, use:
python script.py category.parameter=new_parameter_val
e.g., python train_recon.py optim.steps=10000
To change a whole config preset, use:
python script.py category=new_category_preset
e.g., python train_recon.py eval=eval_silent
For major adjustments, it is recommended to create your own config presets.
CT Reconstruction
The default reconstruction can be run with:
python train_recon.py \
model.data_source_path=your/path/to/scan/data \
model.model_path=path/where/trained/model/should/be/saved
Parameters unique to reconstruction
Model:
- init_mode:
prior- Warm-start the optimization from a volume prior fitted withtrain_volume. Requires setting prior_path to a valid model (see below)precomputed- Load initialized Gaussians from a precomputed point cloud. Legacy from the separate r2_gaussian init procedure (expects aninit_[data_name].npyfile in the data folder).
- prior_path - Absolute path to the
point_cloud.picklemodel file that should be loaded wheninit_mode=prior
Optimization:
- tv_vol_size - Side length (in voxels) of the cube that is randomly sampled for the 3D TV loss during reconstruction
Volume fitting
Volume fitting can be split into two categories:
-
Fitting for warm-starting CT reconstruction with a volumetric prior. The target volume is assumed to be named
vol_prior.[npy/tiff](controlled withmodel.vol_name):python train_volume.py \ model.data_source_path=your/path/to/volume/data \ model.model_path=path/where/trained/model/should/be/saved -
Fitting for volume compression, or simply for creating a Gaussian-based representation. Target volume is assumed to be named
vol_gt.[npy/tiff]. Here we train for longer to get a closer match:python train_volume.py \ --config-name compress_volume \ model.data_source_path=your/path/to/volume/data \ model.model_path=path/where/trained/model/should/be/saved
Parameters unique to volume fitting
Model:
- vol_name - Name (without extension) of the ground-truth volume inside the dataset directory that should be fitted, e.g.,
vol_priororvol_gt
Optimization:
- quantize - Enables straight-through estimator quantization of Gaussian positions/scales/rotations/densities during training for model-size control. Useful for GS-based compression
- pos_bits / scale_bits / rot_bits / feat_bits - Bit precision allocated to xyz, scale, rotation and density/features when
quantize=True(also used by the model size reporter)
CT reconstruction from a volumetric prior
First fit the Gaussian representation to a volume (see above). Find path to the trained point cloud (ends with point_cloud.pickle). Then call:
python train_recon.py \
--config-name fromPrior_recon \
model.data_source_path=your/path/to/scan/data \
model.model_path=path/where/trained/model/should/be/saved \
model.prior_path=path/to/trained/point_cloud.pickle \
Testing existing models
Use test_model.py to load a finished checkpoint and report PSNR/SSIM scores without re-running optimization. The script reuses the Hydra config system (defaults to config/default_test.yaml), so point it to your model/data pair just like the training scripts:
python test_model.py \
model.data_source_path=your/path/to/scan/or/volume \
model.model_path=path/to/trained/model \
model.target=recon # or "vol" for volume compression checkpoints
model.vol_name=vol_gt # Target volume name used in volume fitting, ignore for testing recon models
Prepare your own data
Data preparation/generation is largely copied from r2_gaussian.
Our code supports both cone beam and parallel beam configurations.
If you have ground-truth volumes but do not have X-ray projections, follow these instructions to generate your own dataset.
If you have (more than 100) X-ray projections but do not have ground-truth volumes, follow these instructions.
If you want to test your own data, please first convert it to the r2_gaussian format (meta_data.json).
:exclamation: Gaussian initialization is integrated into the reconstruction step for a smoother experience. The separate init capability from r2_gaussian is still retained, but not recommended.
Running experiments from the paper
The experiments/ folder contains ready-made shells for each study discussed in the paper:
main_experiment.sh– Reconstructions for all scans in the r2_gaussian dataset (Tab. 1).time_limit_teaser_experiment.sh– Chest/walnut/coral reconstructions capped at fixed training-time budgets (30 s / 60 s / 120 s) (Fig 1).scaling_study_coral_100it.sh– Scaling capability - 100-iteration reconstruction time for coral scans with increasing volume size (Fig 4a).scaling_study_coral_090ssim.sh– Scaling capability - above, but stop reconstruction once 3D SSIM reaches 0.90 (Fig 4b).init_comparison_experiment.sh– Comparing the impact of various initialization strategies (Fig. 5)compression_experiment.sh– Quality of volume fitting and compression (Fig. 6, Tab. 2)warm_start_experiment.sh– Impact of warm-start on reconstruction speed and quality (Supplementary material, Tab. 3)gaussian_study_r2data_experiment.shandgaussian_study_coraldata_experiment.sh– Ablation study on the impact of the initial number of Gaussians on reconstruction quality (Supplementary material, Fig. 8). :exclamation: Warning - slow.
All scripts default to $(pwd) as the root for data and model outputs. To run them on a different storage location, export MAIN_ROOT=/path/to/root before launching, e.g.
export MAIN_ROOT=/my/data/and/models/path
source experiments/main_experiment.sh
Each shell wraps the corresponding helper in experiments/helpers/ to collect metrics into CSV files right after the training finishes.
Citation
If this repository has helped your research, please consider citing our work:
@misc{pieta2026,
title={FaCT-GS: Fast and Scalable CT Reconstruction with Gaussian Splatting},
author={Pawel Tomasz Pieta and Rasmus Juul Pedersen and Sina Borgi and Jakob Sauer Jørgensen and Jens Wenzel Andreasen and Vedrana Andersen Dahl},
year={2026},
eprint={2604.01844},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2604.01844},
}
Acknowledgements
Based on r2_gaussian. Inspired by image-gs, taming-3dgs, StopThePop.
License
MIT License, excluding the contents of folders fact_gs/r2_gaussian and fact_gs/submodules. See LICENSE file for details.