# batchgenerators treats 2D and 3D augmentation as the same problem

> batchgenerators is a data augmentation framework from the German Cancer Research Center and the Helmholtz Imaging Platform, built for medical images where a transform has to work on a slice and a volume alike. Its contract is a plain dictionary, its extension point is a generate_train_batch method, and its most interesting transforms come straight out of MICCAI and Nature papers.

**MIC-DKFZ/batchgenerators** — A framework for data augmentation for 2D and 3D image classification and segmentation

- Repository: https://github.com/MIC-DKFZ/batchgenerators
- Stars: 1,175 · Forks: 233
- Language: Jupyter Notebook
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/mic-dkfz-batchgenerators

## One transform set for slices and volumes

batchgenerators is a Python package for data augmentation, developed jointly between the Division of Medical Image Computing at the German Cancer Research Center, DKFZ, and the Applied Computer Vision Lab of the Helmholtz Imaging Platform.

The framing in the repository description is a framework for data augmentation for 2D and 3D image classification and segmentation, and the README makes the dimension point explicitly: it supports a variety of augmentations, all of which are compatible with 2D and 3D input data, and it notes that this is something that was missing in most other frameworks.

That is the whole thesis, and it is more important than it sounds. Medical imaging projects are routinely a mix. A tumour segmentation model may be trained on 3D volumes, evaluated on 2D slices, and prototyped on 2D patches cropped out of a volume, often in the same repository. With a framework that treats dimensionality as a property of the array, a change of experiment is a change of input shape. With a framework that does not, it is a rewrite of the augmentation pipeline and a re validation of every result, because a different augmentation is a different experiment.

The primary language of the repository is listed as Jupyter Notebook, which reflects where the work happens. The examples are notebooks, the documentation is a set of worked examples, and the source lives in the batchgenerators directory.

The licence is Apache 2.0, and the project asks that usage comply with it and that the work be cited, with a specific reference to the 2020 batchgenerators paper and a Zenodo DOI. The project is also upfront about its quality. It is not, in the words of the README, yet perfect, but it is good enough to be shared with the community, and bugs are handled by opening an issue.

## The data contract is a dictionary, and that is the design decision

The data structure used internally, and which you have to comply with when implementing generate_train_batch, is kept simple: it is just a regular Python dictionary. The README says this was done to allow maximum flexibility in the kind of data passed along through the pipeline.

The rules are few. The dictionary must have a data key and value pair. It optionally can handle a seg key and value pair to hold a segmentation, and if a seg pair is present, all spatial transformations will also be applied to the segmentation. Apart from data and seg you are free to do whatever you want, for example with your image classification or regression target, and all key and value pairs other than data and seg will be passed through the pipeline unmodified.

The shapes are strict. The data value must have shape (b, c, x, y) for 2D or (b, c, x, y, z) for 3D, and the seg value must have the same shapes. The colour channel may be used in seg to hold several segmentation maps, and if you have only one segmentation you should make sure it has shape (b, 1, x, y (, z)).

This is the part worth thinking about before you adopt the framework, because it is a constraint on your code rather than a convenience. A dictionary with a fixed key contract means the framework cannot know your data. The augmentation pipeline has no idea what your target is, what your metadata is, or how many channels of segmentation you have beyond the leading dimension, and it passes all of that through untouched.

The trade is that the framework never has to be extended for a new kind of task, and the cost is that the shape convention is not negotiable. If your data does not already look like a batched channel-first array, you will be reshaping it at the boundary of your own code.

## You subclass a data loader and write one method

The working principle of the framework is stated in three steps: derive from the DataLoaderBase class, reimplement the generate_train_batch member function, and use it to stack your augmentations.

That is the extension point, and it is deliberately small. The framework does not ask to know where your files are or how they are loaded, it asks you to be able to produce a batch in the dictionary shape it defines, and it takes care of the augmentation, the multithreading and the pinning.

Stacking is done with the Compose transform, batchgenerators.transforms.abstract_transforms.Compose, and the composed transform is then plugged into the multithreader, batchgenerators.dataloading.multi_threaded_augmenter.MultiThreadedAugmenter. The README spells out that sequence, stack the transforms, finish by plugging the composed transform into the multithreader.

The examples show how much of the framework you can borrow. There is a simple example notebook at batchgenerators/examples/example_ipynb.ipynb, a heavily commented one at batchgenerators/examples/multithreaded_with_batches.ipynb that gives an idea of the interplay between the SlimDataLoaderBase and the MultiThreadedAugmentor, and an extensive example for BraTS2017 and 2018 with both 2D and 3D data loaders and augmentations under batchgenerators/examples/brats2017.

The BraTS example is the one to read if you are doing medical imaging, since BraTS is a brain tumour segmentation challenge and the example covers the volume case as well as the slice case. There are also CIFAR10 and CIFAR100 datasets and a data loader at batchgenerators/datasets/cifar.py, which is a small, fast way to try the framework on something that is not medical data at all.

## The catalogue is four families, and the noise family is still growing

The supported augmentations are listed by family, and the list is where you can see what the framework actually covers.

Spatial augmentations come first, and they are the ones that matter most in 3D. Mirroring, channel translation to simulate registration errors, elastic deformations, rotations, scaling, resampling, and multi channel misalignments. Channel translation and multi channel misalignments are both about registration error, which is a specific problem in multi modal imaging, where a CT and an MRI of the same patient are never perfectly aligned and a model that assumes they are will fail on real data.

Colour augmentations are brightness, in additive and multiplicative form, contrast, and gamma, which the README compares to gamma correction in photo editing. That comparison is apt, because that is what it is: the same non linear adjustment of the intensity mapping that a photographer applies, applied to a volume.

Noise augmentations are Gaussian noise and Rician noise, and the README says more will be expanded in future commits. Rician noise is the correct model for magnitude data in MRI, where noise follows a Rice distribution rather than a Gaussian one, so the two entries are not the same noise twice.

Cropping covers random crop, center crop and padding, and padding is worth noting because it is how you handle a volume whose dimensions are not a multiple of your patch size.

And there is a separate entry for anatomy informed augmentation, which is the framework's own research contribution rather than a generic transform, and is covered in its own section below.

## Two transforms that come from published medical imaging work

Two augmentations in the package are application specific, and they are the reason a research group published this rather than shipping a utility library.

The first is Anatomy-informed Data Augmentation, proposed at MICCAI 2023, for the simulation of soft tissue deformations. The implementation details live in a separate repository, MIC-DKFZ/anatomy_informed_DA. The idea, in one line, is that a generic elastic deformation warps anatomy in ways that are anatomically impossible, and an augmentation that knows the shape of the organ being deformed produces deformations that a model will actually see in the scanner.

The second is Misalignment Data Augmentation, proposed in Nature Scientific Reports 2023, for enhancing a model's adaptability to diverse misalignments between multi-modal, multi-channel images, with the goal of stable performance under such misalignment. Its implementation details are in MIC-DKFZ/misalignment_DA.

The release notes record when each arrived. Version 0.23.1 added the anatomy informed data augmentation, and 0.23.2 added the misalignment data augmentation.

That these are separate repositories is worth noting, because it shows the structure of the project. batchgenerators is the general framework, the research prototypes live next door, and the framework is where they were consolidated. The README asks that these augmentations be cited separately if you use them, which is the correct instruction for work that appeared in a conference and a journal respectively.

## Windows needs a main guard and freeze_support

There is a section of the README with a warning in the heading, and it is the one that bites people on a laptop.

Windows support is very experimental, and the reason given is specific: batchgenerators makes heavy use of Python multiprocessing, and multiprocessing on Windows is different from Linux. To prevent the workers from freezing on Windows, you have to guard your code with if __name__ == '__main__' and use multiprocessing's freeze_support. The executed script may then look like this:

```python
# some imports and functions here

def main():
    # do some stuff

if __name__ == '__main__':
    from multiprocessing import freeze_support
    freeze_support()
    main()
```

And this is not required on Linux.

The reason for the requirement is the standard one. On Linux, multiprocessing uses fork, so the child processes inherit the parent's memory and the guard is unnecessary. On Windows, multiprocessing uses spawn, so each worker re imports the main module, and without the guard the workers re execute the script, which recursively spawns more workers, and the machine appears to freeze.

So the framework is cross platform in principle and Linux first in practice, and the cost of running it on Windows is a small structural requirement in your training script. That is a fair trade for a package that otherwise gives you the same transforms on both platforms, and it is a much smaller cost than the older problems the release notes describe.

There is history here. The 0.19 release notes say Windows is now supported, thanks to a contribution, and the same release added the complete BraTS2017 and 2018 example for both 2D and 3D, with the note that you should use it if you would like to get some insights on how the author does his experiments. The 0.19.5 release then fixed an OMP_NUM_THREADS issue by using the threadpoolctl package, and dropped Python 2 support because threadpoolctl is not available for Python 2.

## Version 0.23 broke imports, and the metadata has moved on since

The release notes are the place to look before upgrading, because one entry is a breaking change and the current version is not the one the notes stop at.

Version 0.23 fixed the import mess, with the __init__.py files now empty. The notes are blunt that this is a breaking change for some users and ask you to adapt your imports. The same release introduced local_transforms, and changed resize_segmentation, which now uses the edge mode and no longer takes a cval argument, with the reason given that resizing segmentations with constant border values, which was the previous default, can cause problems and should not be done. That is a good change, and it is also one that changes the output of a segmentation resize, so any result computed with the old default is not comparable to a new one.

Version 0.20.0 fixed a MultiThreadedAugmenter that did not terminate properly after a KeyboardInterrupt, which is the kind of bug that turns Ctrl C into a hung job, fixed an error with the number and order of samples returned when pin_memory is true, and improved performance by always hiding the process to process communication bottleneck through threading.

The version in the project metadata is 0.25.5, but the README's release notes stop at 0.23.2, and the repository has no GitHub releases at all. So the changelog for the most recent versions is not in the readme, and the last push was on 2026-10-15.

The build tooling is plain setuptools, with a setup.py shim and a pyproject.toml, and the Makefile has the usual targets: init to install numpy and the requirements, test running python -m unittest discover, install and install_develop, and documentation running sphinx apidoc. The runtime dependencies are the usual scientific stack, pillow, numpy, scipy, scikit-image, scikit-learn, pandas, threadpoolctl, and a couple of legacy entries, future and unittest2, that the project metadata lists.

So the practical advice is to pin a version, read the changelog between your version and the current one rather than assuming the readme is complete, and to budget half an hour for the import change if you are coming from before 0.23.

## Conclusion

batchgenerators is worth adopting for a medical imaging project where the same pipeline has to handle both 2D slices and 3D volumes, because the transforms are dimension agnostic by construction and the data contract is a plain dictionary that will not fight your existing loader. It is the wrong choice for a project that only needs simple image classification augmentation, since the framework is heavier than that need, and it is the wrong choice if you cannot handle a breaking import change. Before you adopt it, read the 0.23 release note, because the empty __init__.py change is a breaking change for existing users, and note that the metadata version is 0.25.5 while the project publishes no GitHub releases and the last push was on 2026-10-15.

## FAQ

### What is batchgenerators and who develops it?

It is a Python framework for data augmentation for 2D and 3D image classification and segmentation, developed jointly by the Division of Medical Image Computing at the German Cancer Research Center and the Applied Computer Vision Lab of the Helmholtz Imaging Platform. The licence is Apache 2.0 and the project asks that the 2020 paper be cited.

### How do I install batchgenerators and import a transform?

The documented install is pip install --upgrade batchgenerators, and the README shows importing a transform with from batchgenerators.transforms.color_transforms import ContrastAugmentationTransform. The package metadata lists version 0.25.5.

### What data structure does batchgenerators expect?

A plain Python dictionary with a data key and value pair, and optionally a seg key holding a segmentation, whose shape is (b, c, x, y) for 2D or (b, c, x, y, z) for 3D, with the same shape required for data. All other keys are passed through the pipeline unmodified.

### Which augmentations does batchgenerators support in 2D and 3D?

Spatial ones including mirroring, channel translation for registration errors, elastic deformations, rotations, scaling, resampling and multi-channel misalignments, colour ones including brightness, contrast and gamma, noise ones including Gaussian and Rician, cropping with random crop, center crop and padding, and the anatomy-informed augmentation.

### What special handling does batchgenerators need on Windows?

The README states that Windows support is very experimental because the package makes heavy use of Python multiprocessing, which differs on Windows. You have to guard your code with if __name__ == '__main__' and call multiprocessing's freeze_support, and the requirement does not apply on Linux.

## Sources

- [Issues](https://github.com/MIC-DKFZ/batchgenerators/issues)
- [License: Apache-2.0](https://github.com/MIC-DKFZ/batchgenerators/blob/master/LICENSE)
- [MIC-DKFZ/batchgenerators on GitHub](https://github.com/MIC-DKFZ/batchgenerators)
- [README](https://github.com/MIC-DKFZ/batchgenerators/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mic-dkfz-batchgenerators
