VoxelMorph: unsupervised registration without ground-truth warps
Unsupervised Learning for Image Registration
At a glance
- What is it?
- VoxelMorph is a Python library for learning-based image registration. Its pitch is that you can train a deformable alignment model from image pairs without ever supplying a ground-truth deformation field, and the repository ships training, registration and Dice-scoring scripts that mostly work out of the box.
- Who is it for?
- Adopt VoxelMorph if you have a fixed-shape image cohort in NIfTI, MGZ or npz form, a GPU, and a need for deformable alignment where no ground-truth warps exist. Do not adopt it if you need a stable API today (the PyTorch branch is described as under active development) or if your data shapes vary per subject, since the training path assumes consistent shapes.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem VoxelMorph targets: alignment without ground-truth deformations
Classical deformable registration is an optimisation problem solved per image pair. You pick a similarity metric, a regulariser, and an optimiser, then run it for every scan you need aligned. Learning-based registration replaces that loop with a network that predicts the deformation in one forward pass. The obstacle is supervision. Nobody has a ground-truth deformation field for a real pair of brain scans, and hand-labelling one is not a realistic option at cohort scale. VoxelMorph's answer is to train without that label. The README describes the default training script as producing an image-to-image registration network with an unsupervised loss, and the repository topics include unsupervised-learning and diffeomorphism. The intended user is a medical imaging or computer vision researcher with a set of same-modality volumes and a segmentation to score against, not someone who wants a one-line command to align two arbitrary photographs. The presence of NIfTI and MGZ support in the training data path, and of atlas-based registration flags, points clearly at volumetric medical data.
How the unsupervised loss and the velocity-field integration fit together
Two mechanisms carry the design. The first is the unsupervised objective: the network warps the moving image and the loss compares the warped result to the fixed image, so the only supervision is the image pair itself. The README names two loss variants and the parameter values found to work for each. For the CC loss function, a reg parameter of 1 is reported as best; for MSE, 0.01. Those are stated as empirical findings on the authors' data, not as universal defaults. The second mechanism is diffeomorphic warping. Rather than predicting a displacement field directly, the model can predict a velocity field and integrate it. The README points at voxelmorph.layers.VecInt for this, noting that integration is done by scaling and squaring, which the authors found efficient. Spatial transforms live in voxelmorph.layers.SpatialTransformer and accept N-dimensional affine and dense transforms with linear and nearest-neighbour interpolation. One detail worth flagging: the README says original development used xy indexing while the project now emphasises ij indexing. That is a coordinate-convention change, and it is exactly the kind of thing that silently transposes a warp if you mix old code with new. The MICCAI parameter set is also affected. The README states that parameters were originally applied after scaling the velocity field, that this has been fixed, and that running the original MICCAI2018 mode requires xy indexing plus the use_miccai_int network option.
Installing VoxelMorph and picking the right branch
The published package installs from PyPI with pip install voxelmorph. For source development the README gives pip install git+https://github.com/voxelmorph/voxelmorph.git instead. Branch choice matters more than usual here. The default branch is dev, and the README carries a warning that VoxelMorph PyTorch is under active development and that interfaces may change. Users who want the stable TensorFlow version are told to pull or clone the dev-tensorflow branch. That split shows up in the example commands as well: the training, registration and testing examples in the README all live under ./scripts/tf/. So the documented end-to-end workflow, as written, is the TensorFlow one. If you are evaluating the PyTorch path, the README does not give you equivalent script examples, and you should treat the API as unsettled. The repository also uses pre-commit to run pycodestyle before commits, installed with pip install pre-commit followed by pre-commit install, and runnable manually as pre-commit run pycodestyle --all-files. That is a contributor concern, not a runtime dependency.
Training, registering and scoring: the scripts and their flags
Training takes a text file listing image paths and an output directory. The README's example is ./scripts/tf/train.py --img-list /images/list.txt --model-dir /models/output --gpu 0. Weights go to the path given by --model-dir. Data can be NIfTI, MGZ, or npz, and for npz the convention is a vol parameter holding the image and an optional seg parameter holding a discrete segmentation for semi-supervised learning. The README states that all training image data is assumed to have consistent shape, with the note that a customised generator can handle the inconsistent case. Two flags change the model's character. --atlas atlas.npz enables image-to-atlas registration. --int-steps 0 removes flow integration, giving the original dense CVPR network without diffeomorphism. --img-prefix and --img-suffix prepend or append a constant string to each path in the list, which is a small convenience that saves rewriting a file list when data moves. Registration is a separate script: ./scripts/tf/register.py --moving moving.nii.gz --fixed atlas.nii.gz --moved warped.nii.gz --model model.h5 --gpu 0, with --save-warp to also write the predicted deformation field. Both npz and NIfTI inputs and outputs are accepted there. Quality measurement is a third script: ./scripts/tf/test.py --model model.h5 --atlas atlas.npz --scans scan01.npz scan02.npz scan03.npz --labels labels.npz, which computes Dice overlap between the atlas segmentation and the warped test segmentations. The atlas and scan npz files carry vol and seg; labels.npz holds the anatomical label list to include in the score. Note that Dice here is segmentation-based, so a model can score well on Dice while producing a warp you would not want to use for a task that depends on the deformation field itself.
Where VoxelMorph is the wrong tool
The shape assumption is the first real constraint. The README says consistent training shape is assumed, and that customising voxelmorph/generators.py is likely necessary for your own datasets and formats. If your cohort varies in voxel spacing, orientation or matrix size, you are doing preprocessing and generator work before VoxelMorph does anything for you. The second constraint is the branch situation. A default branch named dev carrying an explicit warning that interfaces may change is not a stability promise, and there are no releases retrieved for this repository, so there is no tagged version to pin against. Third, this is a research library with a training requirement. If you need to register two images today and you have no trained model, the pre-trained model list is the only path, and the README defers that list to data/readme.md#models rather than describing it inline. Fourth, the unsupervised loss optimises image similarity. On multi-modal pairs, where intensities do not correspond, a plain intensity-based similarity term is a poor fit; the README's CT-to-MRI SynthMorph demo exists precisely because that case needs a different treatment, clipping the Hounsfield scale. Finally, the parameter values quoted (reg of 1 for CC, 0.01 for MSE, image_sigma=0.01 and prior_lambda=25 for MICCAI) were found best on the authors' data. Treating them as defaults for your cohort is an assumption, not a documented guarantee.
SynthMorph and the no-data training route
The tutorial list contains an alternative worth understanding, because it changes the data requirement rather than the architecture. A deformable SynthMorph demo is described as showing how to train a registration model without data, and a separate affine SynthMorph demo covers learning anatomy-aware and acquisition-agnostic affine registration. The mechanism implied by 'without data' is that training pairs are synthesised rather than drawn from a cohort, which sidesteps the collection and preprocessing burden that the standard training script imposes. That is a genuinely different trade-off from the main path: you give up the guarantee that your training distribution resembles your target images, and you gain the ability to train when you have no paired cohort at all. The acquisition-agnostic affine demo is the relevant one if your problem is multi-modal, since it targets exactly the intensity-mismatch case that defeats a plain similarity loss. These are Colab notebooks, so the practical cost of trying them is low, but they are separate from the pip-installed library and their code is not the same as the scripts/tf path.
Maintenance, licence and what to check before you commit
The repository is not archived and was last pushed in August 2026, so it is being worked on. That activity is concentrated on the dev branch, which is also the branch carrying the interface warning. The practical maintenance cost for an adopter is therefore not just keeping a dependency current; it is that the code you build against may move, and there is no release to pin. The Apache-2.0 licence is permissive and includes an explicit patent grant, which matters for a method that has been published at CVPR and MICCAI. It also carries attribution and notice requirements, so redistributing a modified copy means retaining the relevant notices. This is a description of the licence text, not legal advice; if you are shipping VoxelMorph inside a product, have counsel read the NOTICE and modification clauses rather than taking this paragraph as clearance. Two verification steps are worth doing before you invest: confirm which branch your install resolves to, since the stable TensorFlow code is on dev-tensorflow while the default is dev, and run the Dice test script on a held-out scan set with your own labels.npz, because that is the only quality signal the README gives you and it measures segmentation overlap rather than the fidelity of the deformation field you may actually care about.
Editorial conclusion
Adopt VoxelMorph if you have a fixed-shape image cohort in NIfTI, MGZ or npz form, a GPU, and a need for deformable alignment where no ground-truth warps exist. Do not adopt it if you need a stable API today (the PyTorch branch is described as under active development) or if your data shapes vary per subject, since the training path assumes consistent shapes. Before committing, verify two things yourself: which branch you are installing from, because the stable TensorFlow code lives on dev-tensorflow while the default branch is dev, and whether your task needs diffeomorphic warps, because the README states that --int-steps 0 gives you the original dense CVPR network with no diffeomorphism.
Community notes