caideface 0.3.1__tar.gz → 0.3.3__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 (39) hide show
  1. {caideface-0.3.1 → caideface-0.3.3}/PKG-INFO +63 -20
  2. {caideface-0.3.1 → caideface-0.3.3}/README.md +62 -19
  3. {caideface-0.3.1 → caideface-0.3.3}/pyproject.toml +1 -1
  4. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/__init__.py +1 -1
  5. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/cli.py +2 -3
  6. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ct_face_mask.nii.gz +0 -0
  7. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/pipeline.py +2 -3
  8. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/reorient.py +12 -22
  9. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/skull_strip.py +17 -7
  10. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/PKG-INFO +63 -20
  11. {caideface-0.3.1 → caideface-0.3.3}/tests/test_reorient.py +5 -5
  12. {caideface-0.3.1 → caideface-0.3.3}/setup.cfg +0 -0
  13. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/anonymize.py +0 -0
  14. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/background.py +0 -0
  15. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/mni_icbm152_t1_tal_nlin_sym_55_ext_brain_only.nii.gz +0 -0
  16. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/config.cfg +0 -0
  17. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/meta.json +0 -0
  18. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/ner/cfg +0 -0
  19. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/ner/model +0 -0
  20. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/ner/moves +0 -0
  21. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/tok2vec/cfg +0 -0
  22. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/tok2vec/model +0 -0
  23. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/tokenizer +0 -0
  24. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/vocab/key2row +0 -0
  25. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/vocab/lookups.bin +0 -0
  26. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/vocab/strings.json +0 -0
  27. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/vocab/vectors +0 -0
  28. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/ner_model/vocab/vectors.cfg +0 -0
  29. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/data/t1_mask.nii.gz +0 -0
  30. {caideface-0.3.1 → caideface-0.3.3}/src/caideface/register.py +0 -0
  31. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/SOURCES.txt +0 -0
  32. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/dependency_links.txt +0 -0
  33. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/entry_points.txt +0 -0
  34. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/requires.txt +0 -0
  35. {caideface-0.3.1 → caideface-0.3.3}/src/caideface.egg-info/top_level.txt +0 -0
  36. {caideface-0.3.1 → caideface-0.3.3}/tests/test_anonymize.py +0 -0
  37. {caideface-0.3.1 → caideface-0.3.3}/tests/test_background.py +0 -0
  38. {caideface-0.3.1 → caideface-0.3.3}/tests/test_register.py +0 -0
  39. {caideface-0.3.1 → caideface-0.3.3}/tests/test_skull_strip.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: caideface
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: MRI defacing pipeline with skull-stripping and affine registration from cai4cai
5
5
  Author-email: Lorena Garcia-Foncillas <lorenagarfon00@gmail.com>
6
6
  License: Apache-2.0
@@ -31,28 +31,35 @@ Requires-Dist: TotalSegmentator; extra == "ct"
31
31
 
32
32
  # caideface
33
33
 
34
- **MRI defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
34
+ **MRI and CT defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
35
35
 
36
36
  This package provides two complementary anonymisation capabilities:
37
37
 
38
- - **Image defacing** -- removes facial features from head MRI scans while preserving brain structures, as described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
39
- - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique).
38
+ - **Image defacing** -- removes facial features from head MRI and CT scans while preserving brain structures. The MRI pipeline is described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
39
+ - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique), as described in *"Evaluation of Named Entity Recognition for Automated Extraction of Present Tumor Size and Personal Names from Radiology Reports Using Spacy"* ([DOI:10.1055/s-0045-1803715](https://doi.org/10.1055/s-0045-1803715)).
40
40
 
41
41
  ## Pipeline overview
42
42
 
43
43
  ### Image defacing pipeline
44
44
 
45
- The defacing pipeline consists of three steps:
45
+ The defacing pipeline supports both **MRI** and **CT** modalities, selected via the required `--modality {mri,ct}` flag. The pipeline consists of three steps, with modality-specific backends:
46
46
 
47
- 1. **Reorientation** -- Aligns NIfTI scans to LAS canonical orientation (MNI152 standard) using nibabel.
48
- 2. **Skull-stripping** -- Extracts brain masks using [HD-BET](https://github.com/MIC-DKFZ/HD-BET), then applies dynamic dilation to preserve peripheral brain structures.
49
- 3. **Registration & Defacing** -- Registers each scan to the MNI152 template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features.
47
+ | Step | MRI | CT |
48
+ |------|-----|-----|
49
+ | 1. Reorientation | RAS | RAS |
50
+ | 2. Brain extraction | [HD-BET](https://github.com/MIC-DKFZ/HD-BET) | [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) |
51
+ | 3. Registration template | MNI152 T1 (bundled) | CT brain atlas (from TotalSegmentator) |
52
+ | Background value | Always 0 | Auto-detected per volume |
53
+
54
+ 1. **Reorientation** -- Aligns NIfTI scans to RAS canonical orientation (MNI152 standard) using nibabel, equivalent to FSL's `fslreorient2std`.
55
+ 2. **Skull-stripping** -- Extracts brain masks, then applies dynamic dilation to preserve peripheral brain structures. MRI uses [HD-BET](https://github.com/MIC-DKFZ/HD-BET); CT uses [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) (brain class from the total segmentation task).
56
+ 3. **Registration & Defacing** -- Registers each scan to a modality-matched template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features. For CT, the background fill value is automatically detected from the volume histogram (~-1000 HU for native encoding).
50
57
 
51
58
  ### Text anonymisation (NER + HIPS)
52
59
 
53
60
  The text anonymisation module uses a trained spaCy Named Entity Recognition (NER) model to identify personal names (`PER` entities) in `.txt` files and replaces them with realistic fake names generated by the [Faker](https://faker.readthedocs.io/) library. This "Hiding in Plain Sight" (HIPS) approach produces anonymised reports that remain naturally readable. Consistent name mapping ensures that the same real name is always replaced with the same fake name within a document.
54
61
 
55
- All required models and data are **bundled with the package**, so no additional downloads are needed.
62
+ All required models and data for MRI defacing and text anonymisation are **bundled with the package**. CT defacing requires installing the optional `[ct]` extra (see [Installation](#installation)).
56
63
 
57
64
  ## Requirements
58
65
 
@@ -66,7 +73,7 @@ All required models and data are **bundled with the package**, so no additional
66
73
  |------|---------|---------|
67
74
  | **BRAINSFit** & **BRAINSResample** | Step 3 | Bundled with [3D Slicer](https://www.slicer.org/) |
68
75
 
69
- > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to LAS (equivalent to `fslreorient2std`).
76
+ > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to RAS (equivalent to `fslreorient2std`).
70
77
 
71
78
  #### Finding BRAINSFit and BRAINSResample
72
79
 
@@ -96,13 +103,21 @@ We recommend using a conda environment:
96
103
  ```bash
97
104
  conda create -n caideface python=3.10 -y
98
105
  conda activate caideface
106
+
107
+ # MRI defacing only
99
108
  pip install caideface
109
+
110
+ # MRI + CT defacing (includes TotalSegmentator)
111
+ pip install caideface[ct]
100
112
  ```
101
113
 
102
114
  Or install from GitHub:
103
115
 
104
116
  ```bash
105
117
  pip install "caideface @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
118
+
119
+ # With CT support
120
+ pip install "caideface[ct] @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
106
121
  ```
107
122
 
108
123
  Or install from source:
@@ -110,10 +125,13 @@ Or install from source:
110
125
  ```bash
111
126
  git clone https://github.com/cai4cai/defacing_pipeline.git
112
127
  cd defacing_pipeline/caideface
113
- pip install -e .
128
+ pip install -e . # MRI only
129
+ pip install -e ".[ct]" # MRI + CT
114
130
  ```
115
131
 
116
132
  > **Note:** caideface requires `numpy<2` (enforced automatically). Some dependencies (HD-BET / nnU-Net) are not yet compatible with NumPy 2.x.
133
+ >
134
+ > **Note:** CT support requires [TotalSegmentator](https://github.com/wasserth/TotalSegmentator), which downloads model weights (~1.5 GB) on first use to `~/.totalsegmentator/`. All inference runs locally -- no scan data is sent externally.
117
135
 
118
136
  ## Usage
119
137
 
@@ -122,7 +140,15 @@ pip install -e .
122
140
  Run all three steps in one command:
123
141
 
124
142
  ```bash
143
+ # MRI
125
144
  caideface run ./input_nifti ./output \
145
+ --modality mri \
146
+ --brainsfit /path/to/BRAINSFit \
147
+ --brainsresample /path/to/BRAINSResample
148
+
149
+ # CT
150
+ caideface run ./input_nifti ./output \
151
+ --modality ct \
126
152
  --brainsfit /path/to/BRAINSFit \
127
153
  --brainsresample /path/to/BRAINSResample
128
154
  ```
@@ -136,12 +162,13 @@ This creates three subdirectories under `./output`:
136
162
 
137
163
  | Flag | Default | Description |
138
164
  |------|---------|-------------|
139
- | `--device` | auto-detected | `cpu` or `cuda` for HD-BET |
140
- | `--no-tta` | on | Disable HD-BET test-time augmentation (faster but less accurate) |
165
+ | `--modality` | *required* | Image modality: `mri` or `ct` |
166
+ | `--device` | auto-detected | `cpu` or `cuda` for brain extraction |
167
+ | `--no-tta` | on | Disable HD-BET test-time augmentation (MRI only) |
141
168
  | `--dilation-mm` | `14.0` | Brain mask dilation in mm |
142
- | `--background` | `0` | Fill value for defaced regions (0 for MRI, -1024 for CT) |
143
- | `--template` | bundled | Custom MNI152 skull-stripped template |
144
- | `--face-mask` | bundled | Custom face mask in MNI152 space |
169
+ | `--background` | auto-detected | Background fill value (auto-detected per volume; override with explicit value) |
170
+ | `--template` | bundled | Custom skull-stripped template |
171
+ | `--face-mask` | bundled | Custom face mask in template space |
145
172
  | `--steps` | `all` | Run specific steps: `reorient`, `skull_strip`, `deface` (comma-separated) |
146
173
  | `-v` | off | Verbose/debug logging |
147
174
 
@@ -151,13 +178,14 @@ Run each step separately for more control:
151
178
 
152
179
  ```bash
153
180
  # Step 1: Reorientation
154
- caideface reorient ./raw_nifti ./reoriented
181
+ caideface reorient ./raw_nifti ./reoriented --modality mri
155
182
 
156
183
  # Step 2: Skull-stripping
157
- caideface skull-strip ./reoriented ./hdbet --device cpu
184
+ caideface skull-strip ./reoriented ./hdbet --modality mri --device cpu
158
185
 
159
186
  # Step 3: Registration & Defacing
160
187
  caideface deface ./reoriented ./hdbet ./defaced \
188
+ --modality mri \
161
189
  --brainsfit /path/to/BRAINSFit \
162
190
  --brainsresample /path/to/BRAINSResample
163
191
  ```
@@ -249,6 +277,7 @@ from caideface import (
249
277
  anonymize_batch, # Text anonymisation (batch)
250
278
  anonymize_single, # Text anonymisation (single file)
251
279
  default_ner_model_path, # Path to bundled NER model
280
+ detect_background_value, # CT/MRI background detection
252
281
  )
253
282
  ```
254
283
 
@@ -299,7 +328,21 @@ If you use this tool, please cite:
299
328
  }
300
329
  ```
301
330
 
302
- If you use HD-BET (skull-stripping, Step 2), please also cite:
331
+ If you use CT defacing (TotalSegmentator, Step 2), please also cite:
332
+
333
+ ```bibtex
334
+ @article{Wasserthal2023,
335
+ author={Wasserthal, Jakob and Breit, Hanns-Christian and Meyer, Manfred T. and Pradella, Maurice and Hinck, Daniel and Sauter, Alexander W. and Heye, Tobias and Boll, Daniel T. and Cyriac, Joshy and Yang, Shan and Bach, Michael and Segeroth, Martin},
336
+ title={TotalSegmentator: Robust Segmentation of 104 Anatomic Structures in CT Images},
337
+ journal={Radiology: Artificial Intelligence},
338
+ volume={5},
339
+ number={5},
340
+ year={2023},
341
+ doi={10.1148/ryai.230024}
342
+ }
343
+ ```
344
+
345
+ If you use HD-BET (MRI skull-stripping, Step 2), please also cite:
303
346
 
304
347
  ```bibtex
305
348
  @article{Isensee2019,
@@ -330,4 +373,4 @@ If you use the text anonymisation (NER + HIPS), please also cite:
330
373
 
331
374
  ## License
332
375
 
333
- This project is licensed under the Apache License 2.0 -- see the [LICENSE](../LICENSE) file for details.
376
+ This project is licensed under the Apache License 2.0 -- see the [LICENSE](https://github.com/cai4cai/defacing_pipeline/blob/main/LICENSE) file for details.
@@ -1,27 +1,34 @@
1
1
  # caideface
2
2
 
3
- **MRI defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
3
+ **MRI and CT defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
4
4
 
5
5
  This package provides two complementary anonymisation capabilities:
6
6
 
7
- - **Image defacing** -- removes facial features from head MRI scans while preserving brain structures, as described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
8
- - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique).
7
+ - **Image defacing** -- removes facial features from head MRI and CT scans while preserving brain structures. The MRI pipeline is described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
8
+ - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique), as described in *"Evaluation of Named Entity Recognition for Automated Extraction of Present Tumor Size and Personal Names from Radiology Reports Using Spacy"* ([DOI:10.1055/s-0045-1803715](https://doi.org/10.1055/s-0045-1803715)).
9
9
 
10
10
  ## Pipeline overview
11
11
 
12
12
  ### Image defacing pipeline
13
13
 
14
- The defacing pipeline consists of three steps:
14
+ The defacing pipeline supports both **MRI** and **CT** modalities, selected via the required `--modality {mri,ct}` flag. The pipeline consists of three steps, with modality-specific backends:
15
15
 
16
- 1. **Reorientation** -- Aligns NIfTI scans to LAS canonical orientation (MNI152 standard) using nibabel.
17
- 2. **Skull-stripping** -- Extracts brain masks using [HD-BET](https://github.com/MIC-DKFZ/HD-BET), then applies dynamic dilation to preserve peripheral brain structures.
18
- 3. **Registration & Defacing** -- Registers each scan to the MNI152 template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features.
16
+ | Step | MRI | CT |
17
+ |------|-----|-----|
18
+ | 1. Reorientation | RAS | RAS |
19
+ | 2. Brain extraction | [HD-BET](https://github.com/MIC-DKFZ/HD-BET) | [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) |
20
+ | 3. Registration template | MNI152 T1 (bundled) | CT brain atlas (from TotalSegmentator) |
21
+ | Background value | Always 0 | Auto-detected per volume |
22
+
23
+ 1. **Reorientation** -- Aligns NIfTI scans to RAS canonical orientation (MNI152 standard) using nibabel, equivalent to FSL's `fslreorient2std`.
24
+ 2. **Skull-stripping** -- Extracts brain masks, then applies dynamic dilation to preserve peripheral brain structures. MRI uses [HD-BET](https://github.com/MIC-DKFZ/HD-BET); CT uses [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) (brain class from the total segmentation task).
25
+ 3. **Registration & Defacing** -- Registers each scan to a modality-matched template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features. For CT, the background fill value is automatically detected from the volume histogram (~-1000 HU for native encoding).
19
26
 
20
27
  ### Text anonymisation (NER + HIPS)
21
28
 
22
29
  The text anonymisation module uses a trained spaCy Named Entity Recognition (NER) model to identify personal names (`PER` entities) in `.txt` files and replaces them with realistic fake names generated by the [Faker](https://faker.readthedocs.io/) library. This "Hiding in Plain Sight" (HIPS) approach produces anonymised reports that remain naturally readable. Consistent name mapping ensures that the same real name is always replaced with the same fake name within a document.
23
30
 
24
- All required models and data are **bundled with the package**, so no additional downloads are needed.
31
+ All required models and data for MRI defacing and text anonymisation are **bundled with the package**. CT defacing requires installing the optional `[ct]` extra (see [Installation](#installation)).
25
32
 
26
33
  ## Requirements
27
34
 
@@ -35,7 +42,7 @@ All required models and data are **bundled with the package**, so no additional
35
42
  |------|---------|---------|
36
43
  | **BRAINSFit** & **BRAINSResample** | Step 3 | Bundled with [3D Slicer](https://www.slicer.org/) |
37
44
 
38
- > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to LAS (equivalent to `fslreorient2std`).
45
+ > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to RAS (equivalent to `fslreorient2std`).
39
46
 
40
47
  #### Finding BRAINSFit and BRAINSResample
41
48
 
@@ -65,13 +72,21 @@ We recommend using a conda environment:
65
72
  ```bash
66
73
  conda create -n caideface python=3.10 -y
67
74
  conda activate caideface
75
+
76
+ # MRI defacing only
68
77
  pip install caideface
78
+
79
+ # MRI + CT defacing (includes TotalSegmentator)
80
+ pip install caideface[ct]
69
81
  ```
70
82
 
71
83
  Or install from GitHub:
72
84
 
73
85
  ```bash
74
86
  pip install "caideface @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
87
+
88
+ # With CT support
89
+ pip install "caideface[ct] @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
75
90
  ```
76
91
 
77
92
  Or install from source:
@@ -79,10 +94,13 @@ Or install from source:
79
94
  ```bash
80
95
  git clone https://github.com/cai4cai/defacing_pipeline.git
81
96
  cd defacing_pipeline/caideface
82
- pip install -e .
97
+ pip install -e . # MRI only
98
+ pip install -e ".[ct]" # MRI + CT
83
99
  ```
84
100
 
85
101
  > **Note:** caideface requires `numpy<2` (enforced automatically). Some dependencies (HD-BET / nnU-Net) are not yet compatible with NumPy 2.x.
102
+ >
103
+ > **Note:** CT support requires [TotalSegmentator](https://github.com/wasserth/TotalSegmentator), which downloads model weights (~1.5 GB) on first use to `~/.totalsegmentator/`. All inference runs locally -- no scan data is sent externally.
86
104
 
87
105
  ## Usage
88
106
 
@@ -91,7 +109,15 @@ pip install -e .
91
109
  Run all three steps in one command:
92
110
 
93
111
  ```bash
112
+ # MRI
94
113
  caideface run ./input_nifti ./output \
114
+ --modality mri \
115
+ --brainsfit /path/to/BRAINSFit \
116
+ --brainsresample /path/to/BRAINSResample
117
+
118
+ # CT
119
+ caideface run ./input_nifti ./output \
120
+ --modality ct \
95
121
  --brainsfit /path/to/BRAINSFit \
96
122
  --brainsresample /path/to/BRAINSResample
97
123
  ```
@@ -105,12 +131,13 @@ This creates three subdirectories under `./output`:
105
131
 
106
132
  | Flag | Default | Description |
107
133
  |------|---------|-------------|
108
- | `--device` | auto-detected | `cpu` or `cuda` for HD-BET |
109
- | `--no-tta` | on | Disable HD-BET test-time augmentation (faster but less accurate) |
134
+ | `--modality` | *required* | Image modality: `mri` or `ct` |
135
+ | `--device` | auto-detected | `cpu` or `cuda` for brain extraction |
136
+ | `--no-tta` | on | Disable HD-BET test-time augmentation (MRI only) |
110
137
  | `--dilation-mm` | `14.0` | Brain mask dilation in mm |
111
- | `--background` | `0` | Fill value for defaced regions (0 for MRI, -1024 for CT) |
112
- | `--template` | bundled | Custom MNI152 skull-stripped template |
113
- | `--face-mask` | bundled | Custom face mask in MNI152 space |
138
+ | `--background` | auto-detected | Background fill value (auto-detected per volume; override with explicit value) |
139
+ | `--template` | bundled | Custom skull-stripped template |
140
+ | `--face-mask` | bundled | Custom face mask in template space |
114
141
  | `--steps` | `all` | Run specific steps: `reorient`, `skull_strip`, `deface` (comma-separated) |
115
142
  | `-v` | off | Verbose/debug logging |
116
143
 
@@ -120,13 +147,14 @@ Run each step separately for more control:
120
147
 
121
148
  ```bash
122
149
  # Step 1: Reorientation
123
- caideface reorient ./raw_nifti ./reoriented
150
+ caideface reorient ./raw_nifti ./reoriented --modality mri
124
151
 
125
152
  # Step 2: Skull-stripping
126
- caideface skull-strip ./reoriented ./hdbet --device cpu
153
+ caideface skull-strip ./reoriented ./hdbet --modality mri --device cpu
127
154
 
128
155
  # Step 3: Registration & Defacing
129
156
  caideface deface ./reoriented ./hdbet ./defaced \
157
+ --modality mri \
130
158
  --brainsfit /path/to/BRAINSFit \
131
159
  --brainsresample /path/to/BRAINSResample
132
160
  ```
@@ -218,6 +246,7 @@ from caideface import (
218
246
  anonymize_batch, # Text anonymisation (batch)
219
247
  anonymize_single, # Text anonymisation (single file)
220
248
  default_ner_model_path, # Path to bundled NER model
249
+ detect_background_value, # CT/MRI background detection
221
250
  )
222
251
  ```
223
252
 
@@ -268,7 +297,21 @@ If you use this tool, please cite:
268
297
  }
269
298
  ```
270
299
 
271
- If you use HD-BET (skull-stripping, Step 2), please also cite:
300
+ If you use CT defacing (TotalSegmentator, Step 2), please also cite:
301
+
302
+ ```bibtex
303
+ @article{Wasserthal2023,
304
+ author={Wasserthal, Jakob and Breit, Hanns-Christian and Meyer, Manfred T. and Pradella, Maurice and Hinck, Daniel and Sauter, Alexander W. and Heye, Tobias and Boll, Daniel T. and Cyriac, Joshy and Yang, Shan and Bach, Michael and Segeroth, Martin},
305
+ title={TotalSegmentator: Robust Segmentation of 104 Anatomic Structures in CT Images},
306
+ journal={Radiology: Artificial Intelligence},
307
+ volume={5},
308
+ number={5},
309
+ year={2023},
310
+ doi={10.1148/ryai.230024}
311
+ }
312
+ ```
313
+
314
+ If you use HD-BET (MRI skull-stripping, Step 2), please also cite:
272
315
 
273
316
  ```bibtex
274
317
  @article{Isensee2019,
@@ -299,4 +342,4 @@ If you use the text anonymisation (NER + HIPS), please also cite:
299
342
 
300
343
  ## License
301
344
 
302
- This project is licensed under the Apache License 2.0 -- see the [LICENSE](../LICENSE) file for details.
345
+ This project is licensed under the Apache License 2.0 -- see the [LICENSE](https://github.com/cai4cai/defacing_pipeline/blob/main/LICENSE) file for details.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "caideface"
7
- version = "0.3.1"
7
+ version = "0.3.3"
8
8
  description = "MRI defacing pipeline with skull-stripping and affine registration from cai4cai"
9
9
  readme = "README.md"
10
10
  license = {text = "Apache-2.0"}
@@ -8,7 +8,7 @@ A three-step pipeline for anonymising head MRI scans:
8
8
  Plus standalone text anonymisation via NER + HIPS (Hiding in Plain Sight).
9
9
  """
10
10
 
11
- __version__ = "0.3.1"
11
+ __version__ = "0.3.3"
12
12
 
13
13
  from .pipeline import DefacePipeline
14
14
  from .reorient import reorient_batch, reorient_single
@@ -49,10 +49,9 @@ def main():
49
49
  run_parser.add_argument("--steps", default="all", help="Steps to run: all, or comma-separated: reorient,skull_strip,deface")
50
50
 
51
51
  # --- reorient ---
52
- reorient_parser = subparsers.add_parser("reorient", help="Step 1: Reorient NIfTI scans", parents=[parent])
52
+ reorient_parser = subparsers.add_parser("reorient", help="Step 1: Reorient NIfTI scans to RAS", parents=[parent])
53
53
  reorient_parser.add_argument("input_dir", help="Directory with NIfTI files")
54
54
  reorient_parser.add_argument("output_dir", help="Output directory for reoriented files")
55
- reorient_parser.add_argument("--modality", required=True, choices=["mri", "ct"], help="Image modality (mri→LAS, ct→RAS)")
56
55
 
57
56
  # --- skull-strip ---
58
57
  ss_parser = subparsers.add_parser("skull-strip", help="Step 2: Skull-strip with HD-BET", parents=[parent])
@@ -118,7 +117,7 @@ def main():
118
117
  sys.exit(1)
119
118
 
120
119
  elif args.command == "reorient":
121
- reorient_batch(args.input_dir, args.output_dir, modality=args.modality)
120
+ reorient_batch(args.input_dir, args.output_dir)
122
121
 
123
122
  elif args.command == "skull-strip":
124
123
  skull_strip_batch(
@@ -97,10 +97,9 @@ class DefacePipeline:
97
97
  # Step 1: Reorientation
98
98
  if "reorient" in run_steps:
99
99
  logger.info("=" * 60)
100
- target = "RAS" if self.modality == "ct" else "LAS"
101
- logger.info("STEP 1: Reorientation to %s", target)
100
+ logger.info("STEP 1: Reorientation to RAS")
102
101
  logger.info("=" * 60)
103
- reorient_log = reorient_batch(input_dir, reoriented_dir, modality=self.modality)
102
+ reorient_log = reorient_batch(input_dir, reoriented_dir)
104
103
  results["reorient_log"] = reorient_log
105
104
  else:
106
105
  logger.info("Skipping Step 1 (reorientation)")
@@ -1,4 +1,4 @@
1
- """Step 1: Reorientation of NIfTI scans using nibabel."""
1
+ """Step 1: Reorientation of NIfTI scans to RAS using nibabel."""
2
2
 
3
3
  import os
4
4
  import logging
@@ -9,18 +9,15 @@ import pandas as pd
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
- # Target orientations per modality
13
- TARGET_ORIENTATIONS = {
14
- "mri": ("L", "A", "S"), # LAS — matches fslreorient2std
15
- "ct": ("R", "A", "S"), # RAS — matches CT brain atlas
16
- }
12
+ # RAS matches the MNI152 standard, fslreorient2std, HD-BET, and the CT brain atlas.
13
+ TARGET_ORIENTATION = ("R", "A", "S")
17
14
 
18
15
 
19
- def reorient_single(input_file: str, output_file: str, modality: str = "mri") -> bool:
20
- """Reorient a single NIfTI file to the target orientation for *modality*.
16
+ def reorient_single(input_file: str, output_file: str) -> bool:
17
+ """Reorient a single NIfTI file to RAS orientation.
21
18
 
22
- MRI is reoriented to LAS (matching ``fslreorient2std`` / MNI152).
23
- CT is reoriented to RAS (matching the CT brain atlas).
19
+ This is equivalent to FSL's ``fslreorient2std`` and matches the
20
+ MNI152 template orientation used by both the MRI and CT pipelines.
24
21
 
25
22
  Parameters
26
23
  ----------
@@ -28,8 +25,6 @@ def reorient_single(input_file: str, output_file: str, modality: str = "mri") ->
28
25
  Path to the input NIfTI (.nii.gz) file.
29
26
  output_file : str
30
27
  Path where the reoriented file will be saved.
31
- modality : str
32
- ``'mri'`` (target LAS) or ``'ct'`` (target RAS).
33
28
 
34
29
  Returns
35
30
  -------
@@ -38,12 +33,10 @@ def reorient_single(input_file: str, output_file: str, modality: str = "mri") ->
38
33
  """
39
34
  os.makedirs(os.path.dirname(output_file), exist_ok=True)
40
35
 
41
- target = TARGET_ORIENTATIONS.get(modality, TARGET_ORIENTATIONS["mri"])
42
-
43
36
  try:
44
37
  img = nib.load(input_file)
45
38
  orig_ornt = io_orientation(img.affine)
46
- target_ornt = axcodes2ornt(target)
39
+ target_ornt = axcodes2ornt(TARGET_ORIENTATION)
47
40
  transform = ornt_transform(orig_ornt, target_ornt)
48
41
  reoriented = img.as_reoriented(transform)
49
42
  nib.save(reoriented, output_file)
@@ -54,8 +47,8 @@ def reorient_single(input_file: str, output_file: str, modality: str = "mri") ->
54
47
  return os.path.exists(output_file)
55
48
 
56
49
 
57
- def reorient_batch(input_dir: str, output_dir: str, modality: str = "mri") -> pd.DataFrame:
58
- """Reorient all NIfTI files found recursively under *input_dir*.
50
+ def reorient_batch(input_dir: str, output_dir: str) -> pd.DataFrame:
51
+ """Reorient all NIfTI files found recursively under *input_dir* to RAS.
59
52
 
60
53
  The directory structure is mirrored under *output_dir*.
61
54
 
@@ -66,8 +59,6 @@ def reorient_batch(input_dir: str, output_dir: str, modality: str = "mri") -> pd
66
59
  output_dir : str
67
60
  Root directory where reoriented files will be saved,
68
61
  preserving the subdirectory structure.
69
- modality : str
70
- ``'mri'`` (target LAS) or ``'ct'`` (target RAS).
71
62
 
72
63
  Returns
73
64
  -------
@@ -77,8 +68,7 @@ def reorient_batch(input_dir: str, output_dir: str, modality: str = "mri") -> pd
77
68
  input_dir = os.path.abspath(input_dir)
78
69
  output_dir = os.path.abspath(output_dir)
79
70
 
80
- target = TARGET_ORIENTATIONS.get(modality, TARGET_ORIENTATIONS["mri"])
81
- logger.info("Target orientation: %s (%s)", "".join(target), modality)
71
+ logger.info("Target orientation: RAS")
82
72
 
83
73
  log_rows = []
84
74
  for root, _dirs, files in os.walk(input_dir):
@@ -91,7 +81,7 @@ def reorient_batch(input_dir: str, output_dir: str, modality: str = "mri") -> pd
91
81
  out_path = os.path.join(output_dir, rel, fname)
92
82
 
93
83
  logger.info("Reorienting %s", input_path)
94
- success = reorient_single(input_path, out_path, modality=modality)
84
+ success = reorient_single(input_path, out_path)
95
85
  log_rows.append({"input": input_path, "output": out_path, "success": success})
96
86
 
97
87
  if success:
@@ -111,21 +111,31 @@ def _extract_brain_totalseg(
111
111
  """
112
112
  try:
113
113
  from totalsegmentator.python_api import totalsegmentator
114
+ import totalsegmentator.config as _ts_config
114
115
  except ImportError:
115
116
  raise ImportError(
116
117
  "TotalSegmentator is required for CT skull-stripping.\n"
117
118
  "Install it with: pip install caideface[ct]"
118
119
  )
119
120
 
121
+ # Disable anonymous usage statistics — no data should leave the machine.
122
+ # Patch send_usage_stats to a no-op so no network calls are made.
123
+ _orig_send = _ts_config.send_usage_stats
124
+ _ts_config.send_usage_stats = lambda *a, **kw: None
125
+
120
126
  ts_device = "cpu" if device == "cpu" else "gpu"
121
127
 
122
- input_img = nib.load(input_file)
123
- brain_mask = totalsegmentator(
124
- input=input_img,
125
- task="total",
126
- roi_subset=["brain"],
127
- device=ts_device,
128
- )
128
+ try:
129
+ input_img = nib.load(input_file)
130
+ brain_mask = totalsegmentator(
131
+ input=input_img,
132
+ task="total",
133
+ roi_subset=["brain"],
134
+ device=ts_device,
135
+ quiet=True,
136
+ )
137
+ finally:
138
+ _ts_config.send_usage_stats = _orig_send
129
139
 
130
140
  # Save the raw binary brain mask
131
141
  mask_data = brain_mask.get_fdata().astype(np.uint8)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: caideface
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: MRI defacing pipeline with skull-stripping and affine registration from cai4cai
5
5
  Author-email: Lorena Garcia-Foncillas <lorenagarfon00@gmail.com>
6
6
  License: Apache-2.0
@@ -31,28 +31,35 @@ Requires-Dist: TotalSegmentator; extra == "ct"
31
31
 
32
32
  # caideface
33
33
 
34
- **MRI defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
34
+ **MRI and CT defacing and text anonymisation toolkit** from the [cai4cai](https://cai4cai.ml/) research group (Contextual Artificial Intelligence for Computer Assisted Interventions).
35
35
 
36
36
  This package provides two complementary anonymisation capabilities:
37
37
 
38
- - **Image defacing** -- removes facial features from head MRI scans while preserving brain structures, as described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
39
- - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique).
38
+ - **Image defacing** -- removes facial features from head MRI and CT scans while preserving brain structures. The MRI pipeline is described in the paper *"A Generalisable Head MRI Defacing Pipeline: Evaluation on 2,566 Meningioma Scans"* ([arXiv:2505.12999](https://arxiv.org/abs/2505.12999)).
39
+ - **Text anonymisation** -- detects personal names in medical reports using a trained spaCy NER model and replaces them with realistic fake names (Hiding in Plain Sight / HIPS technique), as described in *"Evaluation of Named Entity Recognition for Automated Extraction of Present Tumor Size and Personal Names from Radiology Reports Using Spacy"* ([DOI:10.1055/s-0045-1803715](https://doi.org/10.1055/s-0045-1803715)).
40
40
 
41
41
  ## Pipeline overview
42
42
 
43
43
  ### Image defacing pipeline
44
44
 
45
- The defacing pipeline consists of three steps:
45
+ The defacing pipeline supports both **MRI** and **CT** modalities, selected via the required `--modality {mri,ct}` flag. The pipeline consists of three steps, with modality-specific backends:
46
46
 
47
- 1. **Reorientation** -- Aligns NIfTI scans to LAS canonical orientation (MNI152 standard) using nibabel.
48
- 2. **Skull-stripping** -- Extracts brain masks using [HD-BET](https://github.com/MIC-DKFZ/HD-BET), then applies dynamic dilation to preserve peripheral brain structures.
49
- 3. **Registration & Defacing** -- Registers each scan to the MNI152 template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features.
47
+ | Step | MRI | CT |
48
+ |------|-----|-----|
49
+ | 1. Reorientation | RAS | RAS |
50
+ | 2. Brain extraction | [HD-BET](https://github.com/MIC-DKFZ/HD-BET) | [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) |
51
+ | 3. Registration template | MNI152 T1 (bundled) | CT brain atlas (from TotalSegmentator) |
52
+ | Background value | Always 0 | Auto-detected per volume |
53
+
54
+ 1. **Reorientation** -- Aligns NIfTI scans to RAS canonical orientation (MNI152 standard) using nibabel, equivalent to FSL's `fslreorient2std`.
55
+ 2. **Skull-stripping** -- Extracts brain masks, then applies dynamic dilation to preserve peripheral brain structures. MRI uses [HD-BET](https://github.com/MIC-DKFZ/HD-BET); CT uses [TotalSegmentator](https://github.com/wasserth/TotalSegmentator) (brain class from the total segmentation task).
56
+ 3. **Registration & Defacing** -- Registers each scan to a modality-matched template using BRAINSFit (affine), warps a face mask into the scan's space, and applies it to remove facial features. For CT, the background fill value is automatically detected from the volume histogram (~-1000 HU for native encoding).
50
57
 
51
58
  ### Text anonymisation (NER + HIPS)
52
59
 
53
60
  The text anonymisation module uses a trained spaCy Named Entity Recognition (NER) model to identify personal names (`PER` entities) in `.txt` files and replaces them with realistic fake names generated by the [Faker](https://faker.readthedocs.io/) library. This "Hiding in Plain Sight" (HIPS) approach produces anonymised reports that remain naturally readable. Consistent name mapping ensures that the same real name is always replaced with the same fake name within a document.
54
61
 
55
- All required models and data are **bundled with the package**, so no additional downloads are needed.
62
+ All required models and data for MRI defacing and text anonymisation are **bundled with the package**. CT defacing requires installing the optional `[ct]` extra (see [Installation](#installation)).
56
63
 
57
64
  ## Requirements
58
65
 
@@ -66,7 +73,7 @@ All required models and data are **bundled with the package**, so no additional
66
73
  |------|---------|---------|
67
74
  | **BRAINSFit** & **BRAINSResample** | Step 3 | Bundled with [3D Slicer](https://www.slicer.org/) |
68
75
 
69
- > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to LAS (equivalent to `fslreorient2std`).
76
+ > **Note:** Step 1 (reorientation) no longer requires FSL -- it uses nibabel's orientation tools to reorient scans to RAS (equivalent to `fslreorient2std`).
70
77
 
71
78
  #### Finding BRAINSFit and BRAINSResample
72
79
 
@@ -96,13 +103,21 @@ We recommend using a conda environment:
96
103
  ```bash
97
104
  conda create -n caideface python=3.10 -y
98
105
  conda activate caideface
106
+
107
+ # MRI defacing only
99
108
  pip install caideface
109
+
110
+ # MRI + CT defacing (includes TotalSegmentator)
111
+ pip install caideface[ct]
100
112
  ```
101
113
 
102
114
  Or install from GitHub:
103
115
 
104
116
  ```bash
105
117
  pip install "caideface @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
118
+
119
+ # With CT support
120
+ pip install "caideface[ct] @ git+https://github.com/cai4cai/defacing_pipeline.git#subdirectory=caideface"
106
121
  ```
107
122
 
108
123
  Or install from source:
@@ -110,10 +125,13 @@ Or install from source:
110
125
  ```bash
111
126
  git clone https://github.com/cai4cai/defacing_pipeline.git
112
127
  cd defacing_pipeline/caideface
113
- pip install -e .
128
+ pip install -e . # MRI only
129
+ pip install -e ".[ct]" # MRI + CT
114
130
  ```
115
131
 
116
132
  > **Note:** caideface requires `numpy<2` (enforced automatically). Some dependencies (HD-BET / nnU-Net) are not yet compatible with NumPy 2.x.
133
+ >
134
+ > **Note:** CT support requires [TotalSegmentator](https://github.com/wasserth/TotalSegmentator), which downloads model weights (~1.5 GB) on first use to `~/.totalsegmentator/`. All inference runs locally -- no scan data is sent externally.
117
135
 
118
136
  ## Usage
119
137
 
@@ -122,7 +140,15 @@ pip install -e .
122
140
  Run all three steps in one command:
123
141
 
124
142
  ```bash
143
+ # MRI
125
144
  caideface run ./input_nifti ./output \
145
+ --modality mri \
146
+ --brainsfit /path/to/BRAINSFit \
147
+ --brainsresample /path/to/BRAINSResample
148
+
149
+ # CT
150
+ caideface run ./input_nifti ./output \
151
+ --modality ct \
126
152
  --brainsfit /path/to/BRAINSFit \
127
153
  --brainsresample /path/to/BRAINSResample
128
154
  ```
@@ -136,12 +162,13 @@ This creates three subdirectories under `./output`:
136
162
 
137
163
  | Flag | Default | Description |
138
164
  |------|---------|-------------|
139
- | `--device` | auto-detected | `cpu` or `cuda` for HD-BET |
140
- | `--no-tta` | on | Disable HD-BET test-time augmentation (faster but less accurate) |
165
+ | `--modality` | *required* | Image modality: `mri` or `ct` |
166
+ | `--device` | auto-detected | `cpu` or `cuda` for brain extraction |
167
+ | `--no-tta` | on | Disable HD-BET test-time augmentation (MRI only) |
141
168
  | `--dilation-mm` | `14.0` | Brain mask dilation in mm |
142
- | `--background` | `0` | Fill value for defaced regions (0 for MRI, -1024 for CT) |
143
- | `--template` | bundled | Custom MNI152 skull-stripped template |
144
- | `--face-mask` | bundled | Custom face mask in MNI152 space |
169
+ | `--background` | auto-detected | Background fill value (auto-detected per volume; override with explicit value) |
170
+ | `--template` | bundled | Custom skull-stripped template |
171
+ | `--face-mask` | bundled | Custom face mask in template space |
145
172
  | `--steps` | `all` | Run specific steps: `reorient`, `skull_strip`, `deface` (comma-separated) |
146
173
  | `-v` | off | Verbose/debug logging |
147
174
 
@@ -151,13 +178,14 @@ Run each step separately for more control:
151
178
 
152
179
  ```bash
153
180
  # Step 1: Reorientation
154
- caideface reorient ./raw_nifti ./reoriented
181
+ caideface reorient ./raw_nifti ./reoriented --modality mri
155
182
 
156
183
  # Step 2: Skull-stripping
157
- caideface skull-strip ./reoriented ./hdbet --device cpu
184
+ caideface skull-strip ./reoriented ./hdbet --modality mri --device cpu
158
185
 
159
186
  # Step 3: Registration & Defacing
160
187
  caideface deface ./reoriented ./hdbet ./defaced \
188
+ --modality mri \
161
189
  --brainsfit /path/to/BRAINSFit \
162
190
  --brainsresample /path/to/BRAINSResample
163
191
  ```
@@ -249,6 +277,7 @@ from caideface import (
249
277
  anonymize_batch, # Text anonymisation (batch)
250
278
  anonymize_single, # Text anonymisation (single file)
251
279
  default_ner_model_path, # Path to bundled NER model
280
+ detect_background_value, # CT/MRI background detection
252
281
  )
253
282
  ```
254
283
 
@@ -299,7 +328,21 @@ If you use this tool, please cite:
299
328
  }
300
329
  ```
301
330
 
302
- If you use HD-BET (skull-stripping, Step 2), please also cite:
331
+ If you use CT defacing (TotalSegmentator, Step 2), please also cite:
332
+
333
+ ```bibtex
334
+ @article{Wasserthal2023,
335
+ author={Wasserthal, Jakob and Breit, Hanns-Christian and Meyer, Manfred T. and Pradella, Maurice and Hinck, Daniel and Sauter, Alexander W. and Heye, Tobias and Boll, Daniel T. and Cyriac, Joshy and Yang, Shan and Bach, Michael and Segeroth, Martin},
336
+ title={TotalSegmentator: Robust Segmentation of 104 Anatomic Structures in CT Images},
337
+ journal={Radiology: Artificial Intelligence},
338
+ volume={5},
339
+ number={5},
340
+ year={2023},
341
+ doi={10.1148/ryai.230024}
342
+ }
343
+ ```
344
+
345
+ If you use HD-BET (MRI skull-stripping, Step 2), please also cite:
303
346
 
304
347
  ```bibtex
305
348
  @article{Isensee2019,
@@ -330,4 +373,4 @@ If you use the text anonymisation (NER + HIPS), please also cite:
330
373
 
331
374
  ## License
332
375
 
333
- This project is licensed under the Apache License 2.0 -- see the [LICENSE](../LICENSE) file for details.
376
+ This project is licensed under the Apache License 2.0 -- see the [LICENSE](https://github.com/cai4cai/defacing_pipeline/blob/main/LICENSE) file for details.
@@ -30,7 +30,7 @@ def _make_nifti(shape=(64, 64, 32), orientation="PSR", dirpath=None):
30
30
 
31
31
 
32
32
  class TestReorientSingle:
33
- def test_reorients_to_las(self, tmp_path):
33
+ def test_reorients_to_ras(self, tmp_path):
34
34
  input_path = _make_nifti(orientation="PSR", dirpath=str(tmp_path))
35
35
  output_path = os.path.join(str(tmp_path), "output", "reoriented.nii.gz")
36
36
 
@@ -39,10 +39,10 @@ class TestReorientSingle:
39
39
  assert success is True
40
40
  assert os.path.exists(output_path)
41
41
  img = nib.load(output_path)
42
- assert nib.aff2axcodes(img.affine) == ("L", "A", "S")
42
+ assert nib.aff2axcodes(img.affine) == ("R", "A", "S")
43
43
 
44
- def test_already_las_is_unchanged(self, tmp_path):
45
- input_path = _make_nifti(orientation="LAS", dirpath=str(tmp_path))
44
+ def test_already_ras_is_unchanged(self, tmp_path):
45
+ input_path = _make_nifti(orientation="RAS", dirpath=str(tmp_path))
46
46
  output_path = os.path.join(str(tmp_path), "output", "reoriented.nii.gz")
47
47
 
48
48
  success = reorient_single(input_path, output_path)
@@ -86,7 +86,7 @@ class TestReorientSingle:
86
86
  success = reorient_single(input_path, output_path)
87
87
  assert success is True
88
88
  img = nib.load(output_path)
89
- assert nib.aff2axcodes(img.affine) == ("L", "A", "S"), f"Failed for {ornt}"
89
+ assert nib.aff2axcodes(img.affine) == ("R", "A", "S"), f"Failed for {ornt}"
90
90
 
91
91
  def test_invalid_file_returns_false(self, tmp_path):
92
92
  fake_path = os.path.join(str(tmp_path), "nonexistent.nii.gz")
File without changes