medaugmentx 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. medaugmentx-0.2.0/LICENSE +21 -0
  2. medaugmentx-0.2.0/PKG-INFO +330 -0
  3. medaugmentx-0.2.0/README.md +273 -0
  4. medaugmentx-0.2.0/medaugmentx/__init__.py +22 -0
  5. medaugmentx-0.2.0/medaugmentx/core/__init__.py +16 -0
  6. medaugmentx-0.2.0/medaugmentx/core/base.py +81 -0
  7. medaugmentx-0.2.0/medaugmentx/core/compose.py +195 -0
  8. medaugmentx-0.2.0/medaugmentx/core/utils.py +87 -0
  9. medaugmentx-0.2.0/medaugmentx/core/volume.py +117 -0
  10. medaugmentx-0.2.0/medaugmentx/io/__init__.py +18 -0
  11. medaugmentx-0.2.0/medaugmentx/io/dicom.py +195 -0
  12. medaugmentx-0.2.0/medaugmentx/io/nifti.py +101 -0
  13. medaugmentx-0.2.0/medaugmentx/presets.py +226 -0
  14. medaugmentx-0.2.0/medaugmentx/serialization.py +267 -0
  15. medaugmentx-0.2.0/medaugmentx/transforms/__init__.py +54 -0
  16. medaugmentx-0.2.0/medaugmentx/transforms/intensity/__init__.py +18 -0
  17. medaugmentx-0.2.0/medaugmentx/transforms/intensity/bias_field.py +107 -0
  18. medaugmentx-0.2.0/medaugmentx/transforms/intensity/blur.py +165 -0
  19. medaugmentx-0.2.0/medaugmentx/transforms/intensity/brightness_contrast.py +91 -0
  20. medaugmentx-0.2.0/medaugmentx/transforms/intensity/contrast.py +79 -0
  21. medaugmentx-0.2.0/medaugmentx/transforms/intensity/noise.py +130 -0
  22. medaugmentx-0.2.0/medaugmentx/transforms/intensity/window_level.py +116 -0
  23. medaugmentx-0.2.0/medaugmentx/transforms/modality/__init__.py +22 -0
  24. medaugmentx-0.2.0/medaugmentx/transforms/modality/ct/__init__.py +4 -0
  25. medaugmentx-0.2.0/medaugmentx/transforms/modality/ct/beam_hardening.py +108 -0
  26. medaugmentx-0.2.0/medaugmentx/transforms/modality/mri/__init__.py +5 -0
  27. medaugmentx-0.2.0/medaugmentx/transforms/modality/mri/ghosting.py +112 -0
  28. medaugmentx-0.2.0/medaugmentx/transforms/modality/mri/kspace.py +105 -0
  29. medaugmentx-0.2.0/medaugmentx/transforms/modality/tomosynthesis/__init__.py +12 -0
  30. medaugmentx-0.2.0/medaugmentx/transforms/modality/tomosynthesis/blur.py +89 -0
  31. medaugmentx-0.2.0/medaugmentx/transforms/modality/tomosynthesis/dropout.py +82 -0
  32. medaugmentx-0.2.0/medaugmentx/transforms/modality/tomosynthesis/elastic.py +70 -0
  33. medaugmentx-0.2.0/medaugmentx/transforms/modality/tomosynthesis/slab.py +89 -0
  34. medaugmentx-0.2.0/medaugmentx/transforms/spatial/__init__.py +7 -0
  35. medaugmentx-0.2.0/medaugmentx/transforms/spatial/affine.py +187 -0
  36. medaugmentx-0.2.0/medaugmentx/transforms/spatial/crop.py +112 -0
  37. medaugmentx-0.2.0/medaugmentx/transforms/spatial/elastic.py +133 -0
  38. medaugmentx-0.2.0/medaugmentx/transforms/spatial/flip.py +75 -0
  39. medaugmentx-0.2.0/medaugmentx.egg-info/PKG-INFO +330 -0
  40. medaugmentx-0.2.0/medaugmentx.egg-info/SOURCES.txt +45 -0
  41. medaugmentx-0.2.0/medaugmentx.egg-info/dependency_links.txt +1 -0
  42. medaugmentx-0.2.0/medaugmentx.egg-info/requires.txt +32 -0
  43. medaugmentx-0.2.0/medaugmentx.egg-info/top_level.txt +1 -0
  44. medaugmentx-0.2.0/pyproject.toml +107 -0
  45. medaugmentx-0.2.0/setup.cfg +4 -0
  46. medaugmentx-0.2.0/tests/test_presets.py +141 -0
  47. medaugmentx-0.2.0/tests/test_serialization.py +193 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MedAugment Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,330 @@
1
+ Metadata-Version: 2.4
2
+ Name: medaugmentx
3
+ Version: 0.2.0
4
+ Summary: Clinically-aware medical image augmentation for AI training (MRI, CT, X-Ray, Tomosynthesis).
5
+ Author: MedAugmentX Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/medaugmentx/medaugmentx
8
+ Project-URL: Documentation, https://github.com/medaugmentx/medaugmentx/tree/main/docs
9
+ Project-URL: Source, https://github.com/medaugmentx/medaugmentx
10
+ Project-URL: Issues, https://github.com/medaugmentx/medaugmentx/issues
11
+ Keywords: medical-imaging,data-augmentation,deep-learning,dicom,nifti,tomosynthesis,mri,ct,radiology-ai
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
25
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
26
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: numpy>=1.22
31
+ Requires-Dist: scipy>=1.9
32
+ Provides-Extra: dicom
33
+ Requires-Dist: pydicom>=2.3; extra == "dicom"
34
+ Provides-Extra: nifti
35
+ Requires-Dist: nibabel>=4.0; extra == "nifti"
36
+ Provides-Extra: io
37
+ Requires-Dist: pydicom>=2.3; extra == "io"
38
+ Requires-Dist: nibabel>=4.0; extra == "io"
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest>=7.0; extra == "test"
41
+ Requires-Dist: pytest-cov>=4.0; extra == "test"
42
+ Requires-Dist: hypothesis>=6.70; extra == "test"
43
+ Requires-Dist: pydicom>=2.3; extra == "test"
44
+ Requires-Dist: nibabel>=4.0; extra == "test"
45
+ Provides-Extra: yaml
46
+ Requires-Dist: pyyaml>=6.0; extra == "yaml"
47
+ Provides-Extra: dev
48
+ Requires-Dist: pytest>=7.0; extra == "dev"
49
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
50
+ Requires-Dist: hypothesis>=6.70; extra == "dev"
51
+ Requires-Dist: pydicom>=2.3; extra == "dev"
52
+ Requires-Dist: nibabel>=4.0; extra == "dev"
53
+ Requires-Dist: pyyaml>=6.0; extra == "dev"
54
+ Requires-Dist: ruff>=0.4; extra == "dev"
55
+ Requires-Dist: mypy>=1.5; extra == "dev"
56
+ Dynamic: license-file
57
+
58
+ # MedAugmentX
59
+
60
+ **Clinically-aware medical image augmentation for AI training.**
61
+
62
+ [![Python](https://img.shields.io/badge/python-3.9%20%E2%80%93%203.14-blue.svg)](https://www.python.org/downloads/)
63
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
64
+ [![Status: Phase 2](https://img.shields.io/badge/status-phase%202-green.svg)](docs/MILESTONES.md)
65
+
66
+ MedAugmentX is a purpose-built Python library for data augmentation of medical
67
+ images. Unlike general-purpose libraries (`torchvision`, `albumentations`), it
68
+ treats the unique properties of medical data — anisotropic 3D volumes,
69
+ modality-specific artifacts, mask consistency, and clinical I/O — as
70
+ first-class concerns.
71
+
72
+ **Zero deep-learning dependencies.** The core library requires only NumPy and
73
+ SciPy. PyTorch, MONAI, and TorchIO interop are planned for Phase 3.
74
+
75
+ ---
76
+
77
+ ## Why MedAugmentX
78
+
79
+ | Problem with general-purpose augmentation | What MedAugmentX does |
80
+ | --- | --- |
81
+ | Treats every image as 2D RGB | Native 3D volumes with anisotropic-aware ops |
82
+ | No MRI-specific noise or artifact models | Physics-based Rician noise, bias field, k-space corruption, ghosting |
83
+ | CT/DXR augmentation is generic brightness shift | Window/level variation, beam hardening, resolution simulation |
84
+ | Masks drift on complex transforms | Deterministic seeding; image and mask share the same random draw |
85
+ | No tomosynthesis support | Dedicated DBT module with slab-aware augmentations |
86
+ | DICOM/NIfTI I/O scattered across libraries | One loader, one `MedVolume`, vendor metadata preserved |
87
+ | Pipelines can't be saved or reloaded | Full JSON/YAML serialisation with round-trip reconstruction |
88
+
89
+ ---
90
+
91
+ ## Install
92
+
93
+ ```bash
94
+ # Core (NumPy + SciPy only)
95
+ pip install medaugmentx
96
+
97
+ # With DICOM/NIfTI I/O
98
+ pip install "medaugmentx[io]"
99
+
100
+ # With YAML serialisation support
101
+ pip install "medaugmentx[yaml]"
102
+ ```
103
+
104
+ Verify the installation:
105
+
106
+ ```python
107
+ import medaugmentx
108
+ print(medaugmentx.__version__) # 0.2.0
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Quick start
114
+
115
+ ### One-line preset
116
+
117
+ The fastest way to get started is a pre-built modality preset:
118
+
119
+ ```python
120
+ from medaugmentx.presets import mri_pipeline, ct_pipeline, dxr_pipeline, dbt_pipeline
121
+
122
+ pipeline = mri_pipeline(seed=42)
123
+ augmented = pipeline(vol) # MedVolume in, MedVolume out
124
+ ```
125
+
126
+ Four presets ship out of the box — see [Preset pipelines](#preset-pipelines) below.
127
+
128
+ ### Build your own pipeline
129
+
130
+ ```python
131
+ import numpy as np
132
+ from medaugmentx import MedVolume, Compose, OneOf
133
+ from medaugmentx.transforms import (
134
+ RandomAffine, ElasticDeform,
135
+ BiasField, RicianNoise, GaussianNoise, GammaCorrection,
136
+ )
137
+
138
+ vol = MedVolume(
139
+ image=np.random.rand(80, 256, 256).astype(np.float32),
140
+ mask=np.zeros((80, 256, 256), dtype=np.uint8),
141
+ spacing=(1.0, 0.7, 0.7), # mm per axis (z, y, x)
142
+ metadata={"modality": "MR"},
143
+ )
144
+
145
+ augment = Compose([
146
+ RandomAffine(rotation=15, scale=(0.9, 1.1), p=0.7),
147
+ ElasticDeform(alpha=(120, 120, 10), sigma=(10, 10, 3), p=0.5),
148
+ BiasField(alpha=0.3, p=0.7),
149
+ OneOf([
150
+ RicianNoise(std=(0.005, 0.02)), # MRI physical noise model
151
+ GaussianNoise(std=0.015), # simpler additive noise
152
+ ], p=0.5),
153
+ GammaCorrection(gamma=(0.8, 1.2), p=0.5),
154
+ ], seed=42)
155
+
156
+ out = augment(vol) # mask kept in sync automatically
157
+ print(out.image.shape, out.mask.shape)
158
+ ```
159
+
160
+ Mask values are preserved exactly — spatial transforms use nearest-neighbour
161
+ interpolation for the mask and the same random draw as the image.
162
+
163
+ ---
164
+
165
+ ## Preset pipelines
166
+
167
+ Ready-to-use `Compose` pipelines for common modalities. All presets are
168
+ seeded, deterministic, and serialisable.
169
+
170
+ ```python
171
+ from medaugmentx.presets import mri_pipeline, ct_pipeline, dxr_pipeline, dbt_pipeline
172
+
173
+ mri = mri_pipeline(seed=42) # bias field, Rician noise, ghosting/k-space
174
+ ct = ct_pipeline(seed=42) # window/level, Gaussian noise, beam hardening
175
+ dxr = dxr_pipeline(seed=42) # blur, brightness/contrast, low-resolution sim
176
+ dbt = dbt_pipeline(seed=42) # slab shift, limited-angle blur, anisotropic elastic
177
+ ```
178
+
179
+ Each preset is a starting point — tune the parameters or swap transforms for
180
+ your dataset.
181
+
182
+ ---
183
+
184
+ ## Serialisation
185
+
186
+ Pipelines serialise to JSON (built-in) or YAML (optional PyYAML):
187
+
188
+ ```python
189
+ from medaugmentx.serialization import to_json, from_json
190
+
191
+ pipeline = mri_pipeline(seed=42)
192
+
193
+ # Save
194
+ json_str = to_json(pipeline)
195
+ with open("pipeline.json", "w") as f:
196
+ f.write(json_str)
197
+
198
+ # Reload — exact same structure, ready to run
199
+ pipeline2 = from_json(open("pipeline.json").read())
200
+ out = pipeline2(vol)
201
+ ```
202
+
203
+ Custom transforms can be added to the registry so they serialise too:
204
+
205
+ ```python
206
+ from medaugmentx.serialization import REGISTRY
207
+ REGISTRY["MyTransform"] = MyTransform
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Loading real volumes
213
+
214
+ ```python
215
+ from medaugmentx.io import load_dicom_series, load_nifti, save_nifti
216
+
217
+ vol_ct = load_dicom_series("/path/to/study/CT_chest/") # MedVolume
218
+ vol_mri = load_nifti("brain_t1.nii.gz") # MedVolume
219
+
220
+ augmented = ct_pipeline(seed=0)(vol_ct)
221
+ save_nifti(augmented, "ct_augmented.nii.gz")
222
+ ```
223
+
224
+ Both loaders populate `spacing` and `metadata` (modality, vendor, DICOM tags)
225
+ automatically.
226
+
227
+ > Requires the `io` extra: `pip install "medaugmentx[io]"`
228
+
229
+ ---
230
+
231
+ ## What's available
232
+
233
+ ### Core
234
+
235
+ | Component | Description |
236
+ | --- | --- |
237
+ | `MedVolume` | Container: image + optional mask + spacing + metadata |
238
+ | `Transform` | Abstract base — probability gating, seedable RNG, `to_dict()` |
239
+ | `Compose` | Sequential pipeline with deterministic child seeding |
240
+ | `OneOf` / `SomeOf` | Random selection from a set of transforms |
241
+
242
+ ### Spatial transforms
243
+
244
+ | Transform | What it does |
245
+ | --- | --- |
246
+ | `RandomAffine` | Rotation + scaling + translation, 2D/3D, axis-aware |
247
+ | `RandomFlip` | Per-axis flip with independent probability |
248
+ | `AnatomicCrop` | Foreground-biased random crop |
249
+ | `ElasticDeform` | Anisotropic B-spline elastic deformation |
250
+
251
+ ### Intensity transforms
252
+
253
+ | Transform | What it does |
254
+ | --- | --- |
255
+ | `GaussianNoise` | Additive zero-mean Gaussian noise |
256
+ | `RicianNoise` | MRI magnitude noise (physically correct for low-SNR regions) |
257
+ | `GammaCorrection` | Power-law contrast, normalisation-aware |
258
+ | `BiasField` | Smooth multiplicative field (MRI coil inhomogeneity) |
259
+ | `WindowLevel` | Random CT window/level shift (protocol variation) |
260
+ | `BrightnessContrast` | Additive brightness + multiplicative contrast |
261
+ | `GaussianBlur` | Isotropic Gaussian blur |
262
+ | `SimulateLowResolution` | Downsample + upsample (cross-site resolution variation) |
263
+
264
+ ### Modality-specific — MRI
265
+
266
+ | Transform | What it does |
267
+ | --- | --- |
268
+ | `GhostingArtifact` | Phase-encoding ghosting (shifted attenuated replica) |
269
+ | `KSpaceDropout` | Random k-space line zeroing with Gibbs ringing reconstruction |
270
+
271
+ ### Modality-specific — CT
272
+
273
+ | Transform | What it does |
274
+ | --- | --- |
275
+ | `BeamHardening` | Radially-symmetric cupping artifact |
276
+
277
+ ### Modality-specific — Tomosynthesis (DBT)
278
+
279
+ | Transform | What it does |
280
+ | --- | --- |
281
+ | `SlabShift` | Z-axis reconstruction-centre variation |
282
+ | `LimitedAngleBlur` | Arc-angle-dependent Z-only blur |
283
+ | `SliceDropout` | Random slice zeroing (robustness) |
284
+ | `AnisotropicElastic` | DBT-default elastic deformation |
285
+
286
+ ### I/O
287
+
288
+ | Helper | Description |
289
+ | --- | --- |
290
+ | `load_dicom_series(path)` | 3D volume from a DICOM series directory |
291
+ | `load_nifti(path)` | MedVolume from `.nii` / `.nii.gz` |
292
+ | `save_nifti(vol, path)` | Write MedVolume to NIfTI |
293
+
294
+ ---
295
+
296
+ ## Reproducibility
297
+
298
+ Every transform is seedable. `Compose(..., seed=42)` produces bit-identical
299
+ output across runs and across machines (within a NumPy version):
300
+
301
+ ```python
302
+ a = Compose([...], seed=42)(vol)
303
+ b = Compose([...], seed=42)(vol)
304
+ assert np.array_equal(a.image, b.image) # always passes
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Project status & roadmap
310
+
311
+ | Phase | Status |
312
+ | --- | --- |
313
+ | **1 — Core MVP** | ✅ Core data model, spatial/intensity transforms, DBT, DICOM/NIfTI I/O |
314
+ | **2 — Modality artifacts & serialisation** | ✅ MRI (bias field, ghosting, k-space), CT (beam hardening), presets, JSON/YAML |
315
+ | **3 — GPU backend, framework interop, v1.0** | Planned |
316
+
317
+ Detailed deliverables: [docs/MILESTONES.md](docs/MILESTONES.md).
318
+
319
+ ---
320
+
321
+ ## Contributing
322
+
323
+ We welcome PRs — new transforms, vendor DICOM coverage, and bug reports with
324
+ sample data are especially valuable. See [CONTRIBUTING.md](CONTRIBUTING.md)
325
+ for the development setup, testing conventions, and the transform-authoring
326
+ template.
327
+
328
+ ## License
329
+
330
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,273 @@
1
+ # MedAugmentX
2
+
3
+ **Clinically-aware medical image augmentation for AI training.**
4
+
5
+ [![Python](https://img.shields.io/badge/python-3.9%20%E2%80%93%203.14-blue.svg)](https://www.python.org/downloads/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![Status: Phase 2](https://img.shields.io/badge/status-phase%202-green.svg)](docs/MILESTONES.md)
8
+
9
+ MedAugmentX is a purpose-built Python library for data augmentation of medical
10
+ images. Unlike general-purpose libraries (`torchvision`, `albumentations`), it
11
+ treats the unique properties of medical data — anisotropic 3D volumes,
12
+ modality-specific artifacts, mask consistency, and clinical I/O — as
13
+ first-class concerns.
14
+
15
+ **Zero deep-learning dependencies.** The core library requires only NumPy and
16
+ SciPy. PyTorch, MONAI, and TorchIO interop are planned for Phase 3.
17
+
18
+ ---
19
+
20
+ ## Why MedAugmentX
21
+
22
+ | Problem with general-purpose augmentation | What MedAugmentX does |
23
+ | --- | --- |
24
+ | Treats every image as 2D RGB | Native 3D volumes with anisotropic-aware ops |
25
+ | No MRI-specific noise or artifact models | Physics-based Rician noise, bias field, k-space corruption, ghosting |
26
+ | CT/DXR augmentation is generic brightness shift | Window/level variation, beam hardening, resolution simulation |
27
+ | Masks drift on complex transforms | Deterministic seeding; image and mask share the same random draw |
28
+ | No tomosynthesis support | Dedicated DBT module with slab-aware augmentations |
29
+ | DICOM/NIfTI I/O scattered across libraries | One loader, one `MedVolume`, vendor metadata preserved |
30
+ | Pipelines can't be saved or reloaded | Full JSON/YAML serialisation with round-trip reconstruction |
31
+
32
+ ---
33
+
34
+ ## Install
35
+
36
+ ```bash
37
+ # Core (NumPy + SciPy only)
38
+ pip install medaugmentx
39
+
40
+ # With DICOM/NIfTI I/O
41
+ pip install "medaugmentx[io]"
42
+
43
+ # With YAML serialisation support
44
+ pip install "medaugmentx[yaml]"
45
+ ```
46
+
47
+ Verify the installation:
48
+
49
+ ```python
50
+ import medaugmentx
51
+ print(medaugmentx.__version__) # 0.2.0
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quick start
57
+
58
+ ### One-line preset
59
+
60
+ The fastest way to get started is a pre-built modality preset:
61
+
62
+ ```python
63
+ from medaugmentx.presets import mri_pipeline, ct_pipeline, dxr_pipeline, dbt_pipeline
64
+
65
+ pipeline = mri_pipeline(seed=42)
66
+ augmented = pipeline(vol) # MedVolume in, MedVolume out
67
+ ```
68
+
69
+ Four presets ship out of the box — see [Preset pipelines](#preset-pipelines) below.
70
+
71
+ ### Build your own pipeline
72
+
73
+ ```python
74
+ import numpy as np
75
+ from medaugmentx import MedVolume, Compose, OneOf
76
+ from medaugmentx.transforms import (
77
+ RandomAffine, ElasticDeform,
78
+ BiasField, RicianNoise, GaussianNoise, GammaCorrection,
79
+ )
80
+
81
+ vol = MedVolume(
82
+ image=np.random.rand(80, 256, 256).astype(np.float32),
83
+ mask=np.zeros((80, 256, 256), dtype=np.uint8),
84
+ spacing=(1.0, 0.7, 0.7), # mm per axis (z, y, x)
85
+ metadata={"modality": "MR"},
86
+ )
87
+
88
+ augment = Compose([
89
+ RandomAffine(rotation=15, scale=(0.9, 1.1), p=0.7),
90
+ ElasticDeform(alpha=(120, 120, 10), sigma=(10, 10, 3), p=0.5),
91
+ BiasField(alpha=0.3, p=0.7),
92
+ OneOf([
93
+ RicianNoise(std=(0.005, 0.02)), # MRI physical noise model
94
+ GaussianNoise(std=0.015), # simpler additive noise
95
+ ], p=0.5),
96
+ GammaCorrection(gamma=(0.8, 1.2), p=0.5),
97
+ ], seed=42)
98
+
99
+ out = augment(vol) # mask kept in sync automatically
100
+ print(out.image.shape, out.mask.shape)
101
+ ```
102
+
103
+ Mask values are preserved exactly — spatial transforms use nearest-neighbour
104
+ interpolation for the mask and the same random draw as the image.
105
+
106
+ ---
107
+
108
+ ## Preset pipelines
109
+
110
+ Ready-to-use `Compose` pipelines for common modalities. All presets are
111
+ seeded, deterministic, and serialisable.
112
+
113
+ ```python
114
+ from medaugmentx.presets import mri_pipeline, ct_pipeline, dxr_pipeline, dbt_pipeline
115
+
116
+ mri = mri_pipeline(seed=42) # bias field, Rician noise, ghosting/k-space
117
+ ct = ct_pipeline(seed=42) # window/level, Gaussian noise, beam hardening
118
+ dxr = dxr_pipeline(seed=42) # blur, brightness/contrast, low-resolution sim
119
+ dbt = dbt_pipeline(seed=42) # slab shift, limited-angle blur, anisotropic elastic
120
+ ```
121
+
122
+ Each preset is a starting point — tune the parameters or swap transforms for
123
+ your dataset.
124
+
125
+ ---
126
+
127
+ ## Serialisation
128
+
129
+ Pipelines serialise to JSON (built-in) or YAML (optional PyYAML):
130
+
131
+ ```python
132
+ from medaugmentx.serialization import to_json, from_json
133
+
134
+ pipeline = mri_pipeline(seed=42)
135
+
136
+ # Save
137
+ json_str = to_json(pipeline)
138
+ with open("pipeline.json", "w") as f:
139
+ f.write(json_str)
140
+
141
+ # Reload — exact same structure, ready to run
142
+ pipeline2 = from_json(open("pipeline.json").read())
143
+ out = pipeline2(vol)
144
+ ```
145
+
146
+ Custom transforms can be added to the registry so they serialise too:
147
+
148
+ ```python
149
+ from medaugmentx.serialization import REGISTRY
150
+ REGISTRY["MyTransform"] = MyTransform
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Loading real volumes
156
+
157
+ ```python
158
+ from medaugmentx.io import load_dicom_series, load_nifti, save_nifti
159
+
160
+ vol_ct = load_dicom_series("/path/to/study/CT_chest/") # MedVolume
161
+ vol_mri = load_nifti("brain_t1.nii.gz") # MedVolume
162
+
163
+ augmented = ct_pipeline(seed=0)(vol_ct)
164
+ save_nifti(augmented, "ct_augmented.nii.gz")
165
+ ```
166
+
167
+ Both loaders populate `spacing` and `metadata` (modality, vendor, DICOM tags)
168
+ automatically.
169
+
170
+ > Requires the `io` extra: `pip install "medaugmentx[io]"`
171
+
172
+ ---
173
+
174
+ ## What's available
175
+
176
+ ### Core
177
+
178
+ | Component | Description |
179
+ | --- | --- |
180
+ | `MedVolume` | Container: image + optional mask + spacing + metadata |
181
+ | `Transform` | Abstract base — probability gating, seedable RNG, `to_dict()` |
182
+ | `Compose` | Sequential pipeline with deterministic child seeding |
183
+ | `OneOf` / `SomeOf` | Random selection from a set of transforms |
184
+
185
+ ### Spatial transforms
186
+
187
+ | Transform | What it does |
188
+ | --- | --- |
189
+ | `RandomAffine` | Rotation + scaling + translation, 2D/3D, axis-aware |
190
+ | `RandomFlip` | Per-axis flip with independent probability |
191
+ | `AnatomicCrop` | Foreground-biased random crop |
192
+ | `ElasticDeform` | Anisotropic B-spline elastic deformation |
193
+
194
+ ### Intensity transforms
195
+
196
+ | Transform | What it does |
197
+ | --- | --- |
198
+ | `GaussianNoise` | Additive zero-mean Gaussian noise |
199
+ | `RicianNoise` | MRI magnitude noise (physically correct for low-SNR regions) |
200
+ | `GammaCorrection` | Power-law contrast, normalisation-aware |
201
+ | `BiasField` | Smooth multiplicative field (MRI coil inhomogeneity) |
202
+ | `WindowLevel` | Random CT window/level shift (protocol variation) |
203
+ | `BrightnessContrast` | Additive brightness + multiplicative contrast |
204
+ | `GaussianBlur` | Isotropic Gaussian blur |
205
+ | `SimulateLowResolution` | Downsample + upsample (cross-site resolution variation) |
206
+
207
+ ### Modality-specific — MRI
208
+
209
+ | Transform | What it does |
210
+ | --- | --- |
211
+ | `GhostingArtifact` | Phase-encoding ghosting (shifted attenuated replica) |
212
+ | `KSpaceDropout` | Random k-space line zeroing with Gibbs ringing reconstruction |
213
+
214
+ ### Modality-specific — CT
215
+
216
+ | Transform | What it does |
217
+ | --- | --- |
218
+ | `BeamHardening` | Radially-symmetric cupping artifact |
219
+
220
+ ### Modality-specific — Tomosynthesis (DBT)
221
+
222
+ | Transform | What it does |
223
+ | --- | --- |
224
+ | `SlabShift` | Z-axis reconstruction-centre variation |
225
+ | `LimitedAngleBlur` | Arc-angle-dependent Z-only blur |
226
+ | `SliceDropout` | Random slice zeroing (robustness) |
227
+ | `AnisotropicElastic` | DBT-default elastic deformation |
228
+
229
+ ### I/O
230
+
231
+ | Helper | Description |
232
+ | --- | --- |
233
+ | `load_dicom_series(path)` | 3D volume from a DICOM series directory |
234
+ | `load_nifti(path)` | MedVolume from `.nii` / `.nii.gz` |
235
+ | `save_nifti(vol, path)` | Write MedVolume to NIfTI |
236
+
237
+ ---
238
+
239
+ ## Reproducibility
240
+
241
+ Every transform is seedable. `Compose(..., seed=42)` produces bit-identical
242
+ output across runs and across machines (within a NumPy version):
243
+
244
+ ```python
245
+ a = Compose([...], seed=42)(vol)
246
+ b = Compose([...], seed=42)(vol)
247
+ assert np.array_equal(a.image, b.image) # always passes
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Project status & roadmap
253
+
254
+ | Phase | Status |
255
+ | --- | --- |
256
+ | **1 — Core MVP** | ✅ Core data model, spatial/intensity transforms, DBT, DICOM/NIfTI I/O |
257
+ | **2 — Modality artifacts & serialisation** | ✅ MRI (bias field, ghosting, k-space), CT (beam hardening), presets, JSON/YAML |
258
+ | **3 — GPU backend, framework interop, v1.0** | Planned |
259
+
260
+ Detailed deliverables: [docs/MILESTONES.md](docs/MILESTONES.md).
261
+
262
+ ---
263
+
264
+ ## Contributing
265
+
266
+ We welcome PRs — new transforms, vendor DICOM coverage, and bug reports with
267
+ sample data are especially valuable. See [CONTRIBUTING.md](CONTRIBUTING.md)
268
+ for the development setup, testing conventions, and the transform-authoring
269
+ template.
270
+
271
+ ## License
272
+
273
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,22 @@
1
+ """MedAugment — clinically-aware medical image augmentation.
2
+
3
+ Public surface for Phase 2.
4
+ """
5
+ from medaugmentx.core import (
6
+ Compose,
7
+ MedVolume,
8
+ OneOf,
9
+ SomeOf,
10
+ Transform,
11
+ )
12
+
13
+ __version__ = "0.2.0"
14
+
15
+ __all__ = [
16
+ "__version__",
17
+ "MedVolume",
18
+ "Transform",
19
+ "Compose",
20
+ "OneOf",
21
+ "SomeOf",
22
+ ]
@@ -0,0 +1,16 @@
1
+ """Core data model and pipeline primitives."""
2
+ from medaugmentx.core.base import Transform
3
+ from medaugmentx.core.compose import Compose, OneOf, SomeOf
4
+ from medaugmentx.core.utils import as_float32, derive_rng, resolve_rng
5
+ from medaugmentx.core.volume import MedVolume
6
+
7
+ __all__ = [
8
+ "MedVolume",
9
+ "Transform",
10
+ "Compose",
11
+ "OneOf",
12
+ "SomeOf",
13
+ "as_float32",
14
+ "derive_rng",
15
+ "resolve_rng",
16
+ ]