ct-segmentation-toolkit 0.2.0__tar.gz → 0.2.1__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 (37) hide show
  1. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/NOTICE +2 -1
  2. ct_segmentation_toolkit-0.2.1/PKG-INFO +216 -0
  3. ct_segmentation_toolkit-0.2.1/README.md +165 -0
  4. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/__init__.py +1 -1
  5. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/__init__.py +8 -7
  6. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/data.py +2 -1
  7. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/denoise_slice.py +2 -1
  8. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/denoise_volume.py +2 -1
  9. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/eval.py +2 -1
  10. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/loss.py +2 -1
  11. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/model.py +2 -1
  12. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/tiffs.py +2 -1
  13. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/train.py +2 -1
  14. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/denoise/utils.py +2 -1
  15. ct_segmentation_toolkit-0.2.1/ct_segmentation_toolkit.egg-info/PKG-INFO +216 -0
  16. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_segmentation_toolkit.egg-info/requires.txt +3 -3
  17. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/pyproject.toml +4 -2
  18. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/tests/test_model.py +1 -1
  19. ct_segmentation_toolkit-0.2.0/PKG-INFO +0 -156
  20. ct_segmentation_toolkit-0.2.0/README.md +0 -107
  21. ct_segmentation_toolkit-0.2.0/ct_segmentation_toolkit.egg-info/PKG-INFO +0 -156
  22. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/LICENSE +0 -0
  23. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/labeling.py +0 -0
  24. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/model.py +0 -0
  25. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/segment.py +0 -0
  26. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/som_bands.py +0 -0
  27. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/tracking.py +0 -0
  28. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/train.py +0 -0
  29. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_seg/viewer.py +0 -0
  30. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_segmentation_toolkit.egg-info/SOURCES.txt +0 -0
  31. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_segmentation_toolkit.egg-info/dependency_links.txt +0 -0
  32. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/ct_segmentation_toolkit.egg-info/top_level.txt +0 -0
  33. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/setup.cfg +0 -0
  34. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/tests/test_denoise.py +0 -0
  35. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/tests/test_segment.py +0 -0
  36. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/tests/test_som_bands.py +0 -0
  37. {ct_segmentation_toolkit-0.2.0 → ct_segmentation_toolkit-0.2.1}/tests/test_tracking.py +0 -0
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
 
16
- This product includes `ct_seg.denoise`, an implementation of the Noise2Inverse framework
16
+ This product includes `ct_seg.denoise`, developed together by Austin Yunker (Argonne
17
+ National Laboratory) and Cameron B. Renteria, implementing the Noise2Inverse framework
17
18
  (Hendriksen, Pelt & Batenburg, IEEE Transactions on Computational Imaging, 2020;
18
19
  https://github.com/ahendriksen/noise2inverse). See ct_seg/denoise/ACKNOWLEDGMENTS.md.
@@ -0,0 +1,216 @@
1
+ Metadata-Version: 2.4
2
+ Name: ct-segmentation-toolkit
3
+ Version: 0.2.1
4
+ Summary: Supervised (U-Net), unsupervised (Otsu/k-means/GMM), and label-free spectral-spatial (SOM) segmentation of scientific image stacks.
5
+ Author-email: "Cameron B. Renteria" <crentb@uw.edu>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/crentb/ct-segmentation-toolkit
8
+ Project-URL: Issues, https://github.com/crentb/ct-segmentation-toolkit/issues
9
+ Keywords: image segmentation,computed tomography,U-Net,self-organizing map,unsupervised,feature extraction,hyperspectral,scientific imaging
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ License-File: NOTICE
25
+ Requires-Dist: numpy>=1.24
26
+ Requires-Dist: scipy>=1.10
27
+ Requires-Dist: scikit-learn>=1.3
28
+ Requires-Dist: scikit-image>=0.21
29
+ Requires-Dist: tifffile>=2023.1
30
+ Requires-Dist: minisom>=2.3
31
+ Requires-Dist: tqdm>=4.65
32
+ Requires-Dist: Pillow>=9.0
33
+ Requires-Dist: matplotlib>=3.7
34
+ Requires-Dist: torch>=2.0
35
+ Provides-Extra: viz
36
+ Requires-Dist: napari[all]>=0.4; extra == "viz"
37
+ Requires-Dist: pyvista>=0.43; extra == "viz"
38
+ Provides-Extra: mlops
39
+ Requires-Dist: mlflow>=2.0; extra == "mlops"
40
+ Provides-Extra: denoise
41
+ Requires-Dist: albumentations>=1.3; extra == "denoise"
42
+ Requires-Dist: PyYAML>=6.0; extra == "denoise"
43
+ Provides-Extra: dev
44
+ Requires-Dist: pytest>=8.0; extra == "dev"
45
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
46
+ Requires-Dist: ruff==0.16.8; extra == "dev"
47
+ Requires-Dist: black==26.5.1; extra == "dev"
48
+ Requires-Dist: mypy==2.3.1; extra == "dev"
49
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
50
+ Dynamic: license-file
51
+
52
+ # ct-segmentation-toolkit
53
+
54
+ Segmentation of scientific image stacks across the full supervision spectrum, from no labels to fully labeled masks, in one tested Python package.
55
+
56
+ [![CI](https://github.com/crentb/ct-segmentation-toolkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/crentb/ct-segmentation-toolkit/actions/workflows/ci.yml)
57
+ [![PyPI](https://img.shields.io/pypi/v/ct-segmentation-toolkit)](https://pypi.org/project/ct-segmentation-toolkit/)
58
+ [![Python](https://img.shields.io/badge/python-3.10--3.14-blue)](https://github.com/crentb/ct-segmentation-toolkit/blob/main/pyproject.toml)
59
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21148567.svg)](https://doi.org/10.5281/zenodo.21148567)
60
+ [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/crentb/ct-segmentation-toolkit/blob/main/LICENSE)
61
+
62
+ ![Pipeline overview: an image stack, optional self-supervised denoising, three segmentation routes chosen by label availability, and per-pixel labels](https://raw.githubusercontent.com/crentb/ct-segmentation-toolkit/main/docs/figures/ct_segmentation_pipeline.png)
63
+
64
+ The toolkit segments volumetric images such as synchrotron and laboratory micro-computed tomography (micro-CT) stacks. It is organized around one practical question: how many labels exist? The unsupervised and label-free routes need none, and the U-Net needs annotated masks. An optional self-supervised denoiser raises the signal-to-noise ratio before any of them. Vector schematic: [docs/ct_segmentation_pipeline.pdf](https://github.com/crentb/ct-segmentation-toolkit/blob/main/docs/ct_segmentation_pipeline.pdf).
65
+
66
+ **Associated preprint:** C. Renteria *et al.*, "Deep learning segmentation of enamel rod architecture from synchrotron computed tomography for bioinspired material design," SSRN (2026), [doi:10.2139/ssrn.6805001](https://doi.org/10.2139/ssrn.6805001).
67
+
68
+ ## Methods
69
+
70
+ | Route | Labels needed | Method | Entry point |
71
+ |---|---|---|---|
72
+ | Unsupervised | none | Multi-Otsu thresholding, k-means, or a Gaussian mixture model (GMM) on intensity | `segment_otsu`, `segment_kmeans`, `segment_gmm` |
73
+ | Label-free spectral-spatial | none | A Self-Organizing Map (SOM) over per-pixel features (multi-scale density, structure-tensor orientation and coherence, a Gabor filter bank, local variance), followed by clustering of the SOM nodes; the same features transfer to hyperspectral cubes | `som_segment` |
74
+ | Supervised | annotated masks | U-Net with training and inference | `UNetSegmentation`, `python -m ct_seg.train` |
75
+ | Denoising (optional) | none | 2.5D Noise2Inverse: a no-skip U-Net trained from one noisy reconstruction, with no clean reference, using a Laplacian Contrast Loss and edge-aware model selection | `ct_seg.denoise` |
76
+
77
+ The denoising subpackage was developed together by Austin Yunker (Argonne National Laboratory) and Cameron B. Renteria; upstream credit is in [ct_seg/denoise/ACKNOWLEDGMENTS.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/ct_seg/denoise/ACKNOWLEDGMENTS.md).
78
+
79
+ ## Installation
80
+
81
+ From PyPI:
82
+
83
+ ```bash
84
+ pip install ct-segmentation-toolkit # classical, SOM, and U-Net segmentation
85
+ pip install "ct-segmentation-toolkit[denoise]" # + Noise2Inverse training (albumentations, PyYAML)
86
+ pip install "ct-segmentation-toolkit[viz]" # + napari labeling and the PyVista viewer
87
+ pip install "ct-segmentation-toolkit[mlops]" # + MLflow experiment tracking
88
+ ```
89
+
90
+ As a signed container image:
91
+
92
+ ```bash
93
+ docker pull ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0
94
+ ```
95
+
96
+ From source, for development:
97
+
98
+ ```bash
99
+ git clone https://github.com/crentb/ct-segmentation-toolkit.git
100
+ cd ct-segmentation-toolkit
101
+ python -m pip install -e ".[dev]" # core + pytest, ruff, black, mypy, pre-commit
102
+ ```
103
+
104
+ ## Quick start
105
+
106
+ Python API:
107
+
108
+ ```python
109
+ import numpy as np
110
+ from ct_seg import segment_kmeans, som_segment, UNetSegmentation
111
+
112
+ volume = np.random.rand(16, 256, 256).astype("float32") # (slices, H, W) in [0, 1]
113
+
114
+ # Unsupervised intensity segmentation (no labels)
115
+ labels, info = segment_kmeans(volume, num_classes=4)
116
+
117
+ # Label-free spectral-spatial segmentation of a single slice
118
+ band_map = som_segment(volume[0], n_clusters=4)
119
+
120
+ # Supervised U-Net
121
+ model = UNetSegmentation(in_channels=1, num_classes=4)
122
+ ```
123
+
124
+ Command line:
125
+
126
+ ```bash
127
+ # Unsupervised (otsu | kmeans | gmm)
128
+ python -m ct_seg.segment --input /path/to/tiffs --method kmeans --num_classes 4 --save_overlay
129
+
130
+ # Train a U-Net, then segment with it
131
+ python -m ct_seg.train --images /path/to/tiffs --masks /path/to/masks --num_classes 4
132
+ python -m ct_seg.segment --input /path/to/tiffs --method unet --model SegOutput/best_model.pth --num_classes 4
133
+ ```
134
+
135
+ The interactive tools `ct_seg.labeling` (napari) and `ct_seg.viewer` (napari and PyVista) require the `[viz]` extra.
136
+
137
+ ## Experiment tracking and profiling
138
+
139
+ Training integrates optional **MLflow** logging of run parameters, per-epoch loss and mean intersection-over-union, and the best checkpoint. With the extra installed it logs automatically; without MLflow, tracking is a no-op and training is unaffected.
140
+
141
+ ```bash
142
+ pip install "ct-segmentation-toolkit[mlops]"
143
+ python -m ct_seg.train --images ... --masks ... --num_classes 4 # logs to ./mlruns
144
+ mlflow ui # browse runs
145
+ ```
146
+
147
+ A reproducible performance profile (forward and training-step latency, throughput, and peak GPU memory) is in [docs/PERF.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/docs/PERF.md):
148
+
149
+ ```bash
150
+ python scripts/profile_unet.py --device cuda --sizes 256 512
151
+ ```
152
+
153
+ ## Repository layout
154
+
155
+ ```text
156
+ ct_seg/
157
+ segment.py classical (Otsu, k-means, GMM) and U-Net segmentation; command line
158
+ som_bands.py spectral-spatial features and SOM segmentation
159
+ model.py U-Net model
160
+ train.py U-Net training command line, with optional MLflow logging
161
+ tracking.py optional MLflow experiment tracking (no-op when MLflow is absent)
162
+ labeling.py napari labeling tool [viz]
163
+ viewer.py napari / PyVista volume viewer [viz]
164
+ denoise/ 2.5D Noise2Inverse: model, loss, training, inference, evaluation
165
+ docs/ overview figure (PNG, PDF, LaTeX source), performance profile, flame graphs
166
+ scripts/ profiling utilities
167
+ tests/ fast CPU test suite; slow tests are marked
168
+ ```
169
+
170
+ ## Testing and continuous integration
171
+
172
+ ```bash
173
+ pytest -m "not slow" # fast suite (what CI runs)
174
+ pytest # everything
175
+ ```
176
+
177
+ Every push and pull request runs one gate, defined in [ci.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/ci.yml):
178
+
179
+ - **Quality:** ruff, black, mypy (advisory), and pytest with coverage on Python 3.10 to 3.14.
180
+ - **Security (blocking):** gitleaks secret detection over the full history, bandit static analysis at medium severity and above, and pip-audit against known vulnerabilities.
181
+ - **Container:** image build, a trivy scan that blocks on fixable critical and high findings, the test suite run inside the image, and an SPDX software bill of materials signed keylessly with cosign.
182
+
183
+ The same gate re-runs weekly on `main` ([scheduled-scan.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/scheduled-scan.yml)), so a newly published vulnerability surfaces without a code change. A version tag re-runs it on the tagged commit before [release.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/release.yml) publishes to PyPI through Trusted Publishing (no stored tokens) and pushes a scanned, cosign-signed image with SLSA build provenance to the GitHub Container Registry. To verify a published image:
184
+
185
+ ```bash
186
+ cosign verify ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0 \
187
+ --certificate-identity-regexp 'github.com/crentb/' \
188
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com
189
+ gh attestation verify oci://ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0 --owner crentb
190
+ ```
191
+
192
+ To report a vulnerability, see [SECURITY.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/SECURITY.md).
193
+
194
+ ## Citation
195
+
196
+ Please cite the software and the associated preprint. GitHub's "Cite this repository" button reads [CITATION.cff](https://github.com/crentb/ct-segmentation-toolkit/blob/main/CITATION.cff).
197
+
198
+ ```bibtex
199
+ @software{renteria_ct_segmentation_toolkit,
200
+ author = {Renteria, Cameron B.},
201
+ title = {ct-segmentation-toolkit},
202
+ version = {0.2.0},
203
+ year = {2026},
204
+ publisher = {Zenodo},
205
+ doi = {10.5281/zenodo.21148567},
206
+ url = {https://github.com/crentb/ct-segmentation-toolkit}
207
+ }
208
+ ```
209
+
210
+ ## Acknowledgments
211
+
212
+ `ct_seg.denoise` implements the Noise2Inverse framework of Hendriksen, Pelt, and Batenburg (*IEEE Transactions on Computational Imaging*, 2020; [original code](https://github.com/ahendriksen/noise2inverse)). See [ct_seg/denoise/ACKNOWLEDGMENTS.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/ct_seg/denoise/ACKNOWLEDGMENTS.md).
213
+
214
+ ## License
215
+
216
+ Apache-2.0. See [LICENSE](https://github.com/crentb/ct-segmentation-toolkit/blob/main/LICENSE) and [NOTICE](https://github.com/crentb/ct-segmentation-toolkit/blob/main/NOTICE).
@@ -0,0 +1,165 @@
1
+ # ct-segmentation-toolkit
2
+
3
+ Segmentation of scientific image stacks across the full supervision spectrum, from no labels to fully labeled masks, in one tested Python package.
4
+
5
+ [![CI](https://github.com/crentb/ct-segmentation-toolkit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/crentb/ct-segmentation-toolkit/actions/workflows/ci.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/ct-segmentation-toolkit)](https://pypi.org/project/ct-segmentation-toolkit/)
7
+ [![Python](https://img.shields.io/badge/python-3.10--3.14-blue)](https://github.com/crentb/ct-segmentation-toolkit/blob/main/pyproject.toml)
8
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21148567.svg)](https://doi.org/10.5281/zenodo.21148567)
9
+ [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/crentb/ct-segmentation-toolkit/blob/main/LICENSE)
10
+
11
+ ![Pipeline overview: an image stack, optional self-supervised denoising, three segmentation routes chosen by label availability, and per-pixel labels](https://raw.githubusercontent.com/crentb/ct-segmentation-toolkit/main/docs/figures/ct_segmentation_pipeline.png)
12
+
13
+ The toolkit segments volumetric images such as synchrotron and laboratory micro-computed tomography (micro-CT) stacks. It is organized around one practical question: how many labels exist? The unsupervised and label-free routes need none, and the U-Net needs annotated masks. An optional self-supervised denoiser raises the signal-to-noise ratio before any of them. Vector schematic: [docs/ct_segmentation_pipeline.pdf](https://github.com/crentb/ct-segmentation-toolkit/blob/main/docs/ct_segmentation_pipeline.pdf).
14
+
15
+ **Associated preprint:** C. Renteria *et al.*, "Deep learning segmentation of enamel rod architecture from synchrotron computed tomography for bioinspired material design," SSRN (2026), [doi:10.2139/ssrn.6805001](https://doi.org/10.2139/ssrn.6805001).
16
+
17
+ ## Methods
18
+
19
+ | Route | Labels needed | Method | Entry point |
20
+ |---|---|---|---|
21
+ | Unsupervised | none | Multi-Otsu thresholding, k-means, or a Gaussian mixture model (GMM) on intensity | `segment_otsu`, `segment_kmeans`, `segment_gmm` |
22
+ | Label-free spectral-spatial | none | A Self-Organizing Map (SOM) over per-pixel features (multi-scale density, structure-tensor orientation and coherence, a Gabor filter bank, local variance), followed by clustering of the SOM nodes; the same features transfer to hyperspectral cubes | `som_segment` |
23
+ | Supervised | annotated masks | U-Net with training and inference | `UNetSegmentation`, `python -m ct_seg.train` |
24
+ | Denoising (optional) | none | 2.5D Noise2Inverse: a no-skip U-Net trained from one noisy reconstruction, with no clean reference, using a Laplacian Contrast Loss and edge-aware model selection | `ct_seg.denoise` |
25
+
26
+ The denoising subpackage was developed together by Austin Yunker (Argonne National Laboratory) and Cameron B. Renteria; upstream credit is in [ct_seg/denoise/ACKNOWLEDGMENTS.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/ct_seg/denoise/ACKNOWLEDGMENTS.md).
27
+
28
+ ## Installation
29
+
30
+ From PyPI:
31
+
32
+ ```bash
33
+ pip install ct-segmentation-toolkit # classical, SOM, and U-Net segmentation
34
+ pip install "ct-segmentation-toolkit[denoise]" # + Noise2Inverse training (albumentations, PyYAML)
35
+ pip install "ct-segmentation-toolkit[viz]" # + napari labeling and the PyVista viewer
36
+ pip install "ct-segmentation-toolkit[mlops]" # + MLflow experiment tracking
37
+ ```
38
+
39
+ As a signed container image:
40
+
41
+ ```bash
42
+ docker pull ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0
43
+ ```
44
+
45
+ From source, for development:
46
+
47
+ ```bash
48
+ git clone https://github.com/crentb/ct-segmentation-toolkit.git
49
+ cd ct-segmentation-toolkit
50
+ python -m pip install -e ".[dev]" # core + pytest, ruff, black, mypy, pre-commit
51
+ ```
52
+
53
+ ## Quick start
54
+
55
+ Python API:
56
+
57
+ ```python
58
+ import numpy as np
59
+ from ct_seg import segment_kmeans, som_segment, UNetSegmentation
60
+
61
+ volume = np.random.rand(16, 256, 256).astype("float32") # (slices, H, W) in [0, 1]
62
+
63
+ # Unsupervised intensity segmentation (no labels)
64
+ labels, info = segment_kmeans(volume, num_classes=4)
65
+
66
+ # Label-free spectral-spatial segmentation of a single slice
67
+ band_map = som_segment(volume[0], n_clusters=4)
68
+
69
+ # Supervised U-Net
70
+ model = UNetSegmentation(in_channels=1, num_classes=4)
71
+ ```
72
+
73
+ Command line:
74
+
75
+ ```bash
76
+ # Unsupervised (otsu | kmeans | gmm)
77
+ python -m ct_seg.segment --input /path/to/tiffs --method kmeans --num_classes 4 --save_overlay
78
+
79
+ # Train a U-Net, then segment with it
80
+ python -m ct_seg.train --images /path/to/tiffs --masks /path/to/masks --num_classes 4
81
+ python -m ct_seg.segment --input /path/to/tiffs --method unet --model SegOutput/best_model.pth --num_classes 4
82
+ ```
83
+
84
+ The interactive tools `ct_seg.labeling` (napari) and `ct_seg.viewer` (napari and PyVista) require the `[viz]` extra.
85
+
86
+ ## Experiment tracking and profiling
87
+
88
+ Training integrates optional **MLflow** logging of run parameters, per-epoch loss and mean intersection-over-union, and the best checkpoint. With the extra installed it logs automatically; without MLflow, tracking is a no-op and training is unaffected.
89
+
90
+ ```bash
91
+ pip install "ct-segmentation-toolkit[mlops]"
92
+ python -m ct_seg.train --images ... --masks ... --num_classes 4 # logs to ./mlruns
93
+ mlflow ui # browse runs
94
+ ```
95
+
96
+ A reproducible performance profile (forward and training-step latency, throughput, and peak GPU memory) is in [docs/PERF.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/docs/PERF.md):
97
+
98
+ ```bash
99
+ python scripts/profile_unet.py --device cuda --sizes 256 512
100
+ ```
101
+
102
+ ## Repository layout
103
+
104
+ ```text
105
+ ct_seg/
106
+ segment.py classical (Otsu, k-means, GMM) and U-Net segmentation; command line
107
+ som_bands.py spectral-spatial features and SOM segmentation
108
+ model.py U-Net model
109
+ train.py U-Net training command line, with optional MLflow logging
110
+ tracking.py optional MLflow experiment tracking (no-op when MLflow is absent)
111
+ labeling.py napari labeling tool [viz]
112
+ viewer.py napari / PyVista volume viewer [viz]
113
+ denoise/ 2.5D Noise2Inverse: model, loss, training, inference, evaluation
114
+ docs/ overview figure (PNG, PDF, LaTeX source), performance profile, flame graphs
115
+ scripts/ profiling utilities
116
+ tests/ fast CPU test suite; slow tests are marked
117
+ ```
118
+
119
+ ## Testing and continuous integration
120
+
121
+ ```bash
122
+ pytest -m "not slow" # fast suite (what CI runs)
123
+ pytest # everything
124
+ ```
125
+
126
+ Every push and pull request runs one gate, defined in [ci.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/ci.yml):
127
+
128
+ - **Quality:** ruff, black, mypy (advisory), and pytest with coverage on Python 3.10 to 3.14.
129
+ - **Security (blocking):** gitleaks secret detection over the full history, bandit static analysis at medium severity and above, and pip-audit against known vulnerabilities.
130
+ - **Container:** image build, a trivy scan that blocks on fixable critical and high findings, the test suite run inside the image, and an SPDX software bill of materials signed keylessly with cosign.
131
+
132
+ The same gate re-runs weekly on `main` ([scheduled-scan.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/scheduled-scan.yml)), so a newly published vulnerability surfaces without a code change. A version tag re-runs it on the tagged commit before [release.yml](https://github.com/crentb/ct-segmentation-toolkit/blob/main/.github/workflows/release.yml) publishes to PyPI through Trusted Publishing (no stored tokens) and pushes a scanned, cosign-signed image with SLSA build provenance to the GitHub Container Registry. To verify a published image:
133
+
134
+ ```bash
135
+ cosign verify ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0 \
136
+ --certificate-identity-regexp 'github.com/crentb/' \
137
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com
138
+ gh attestation verify oci://ghcr.io/crentb/ct-segmentation-toolkit:v0.2.0 --owner crentb
139
+ ```
140
+
141
+ To report a vulnerability, see [SECURITY.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/SECURITY.md).
142
+
143
+ ## Citation
144
+
145
+ Please cite the software and the associated preprint. GitHub's "Cite this repository" button reads [CITATION.cff](https://github.com/crentb/ct-segmentation-toolkit/blob/main/CITATION.cff).
146
+
147
+ ```bibtex
148
+ @software{renteria_ct_segmentation_toolkit,
149
+ author = {Renteria, Cameron B.},
150
+ title = {ct-segmentation-toolkit},
151
+ version = {0.2.0},
152
+ year = {2026},
153
+ publisher = {Zenodo},
154
+ doi = {10.5281/zenodo.21148567},
155
+ url = {https://github.com/crentb/ct-segmentation-toolkit}
156
+ }
157
+ ```
158
+
159
+ ## Acknowledgments
160
+
161
+ `ct_seg.denoise` implements the Noise2Inverse framework of Hendriksen, Pelt, and Batenburg (*IEEE Transactions on Computational Imaging*, 2020; [original code](https://github.com/ahendriksen/noise2inverse)). See [ct_seg/denoise/ACKNOWLEDGMENTS.md](https://github.com/crentb/ct-segmentation-toolkit/blob/main/ct_seg/denoise/ACKNOWLEDGMENTS.md).
162
+
163
+ ## License
164
+
165
+ Apache-2.0. See [LICENSE](https://github.com/crentb/ct-segmentation-toolkit/blob/main/LICENSE) and [NOTICE](https://github.com/crentb/ct-segmentation-toolkit/blob/main/NOTICE).
@@ -34,7 +34,7 @@ from ct_seg.segment import (
34
34
  )
35
35
  from ct_seg.som_bands import extract_features, som_segment
36
36
 
37
- __version__ = "0.1.0"
37
+ __version__ = "0.2.1"
38
38
 
39
39
  # torch-backed exports, resolved lazily on first access (PEP 562).
40
40
  _LAZY_TORCH_EXPORTS = {
@@ -1,16 +1,17 @@
1
1
  """
2
2
  ct_seg.denoise — self-supervised CT denoising (2.5D Noise2Inverse).
3
3
 
4
- Cameron Renteria's own implementation of the Noise2Inverse (N2I) self-supervised
5
- tomography-denoising framework: a no-skip U-Net (Group Normalization, LeakyReLU) trained
6
- to map one sub-reconstruction (e.g. even-angle) to another (odd-angle), so it needs no
7
- clean reference image. His additions over the base method include a 2.5D adjacent-slice
8
- input, a Laplacian Contrast Loss (LCL) for edge preservation, edge-aware model selection,
9
- and automatic GPU batch-size optimization.
4
+ Developed together by Austin Yunker (Argonne National Laboratory) and Cameron B. Renteria.
5
+ An implementation of the Noise2Inverse (N2I) self-supervised tomography-denoising
6
+ framework: a no-skip U-Net (Group Normalization, LeakyReLU) trained to map one
7
+ sub-reconstruction (e.g. even-angle) to another (odd-angle), so it needs no clean
8
+ reference image. Additions over the base method include a 2.5D adjacent-slice input, a
9
+ Laplacian Contrast Loss (LCL) for edge preservation, edge-aware model selection, and
10
+ automatic GPU batch-size optimization.
10
11
 
11
12
  Upstream method (credited): Noise2Inverse - Hendriksen, Pelt & Batenburg, IEEE Transactions
12
13
  on Computational Imaging 6 (2020); original code https://github.com/ahendriksen/noise2inverse
13
- (see ACKNOWLEDGMENTS.md). This subpackage is Copyright 2026 Cameron Renteria, Apache-2.0.
14
+ (see ACKNOWLEDGMENTS.md). This subpackage is licensed Apache-2.0.
14
15
 
15
16
  Only the lightweight building blocks (model, loss, edge score) are exported here. The
16
17
  training/inference CLIs and dataset (`ct_seg.denoise.train`, `denoise_volume`,
@@ -14,7 +14,8 @@ inference pipelines:
14
14
  * InferenceBatchSizeOptimizer - binary-search the largest batch size that fits
15
15
  in GPU memory to avoid out-of-memory errors.
16
16
 
17
- Author: Cameron Renteria <crentb23@gmail.com>
17
+ Authors: Austin Yunker (Argonne National Laboratory),
18
+ Cameron B. Renteria <crentb23@gmail.com>
18
19
  License: Apache-2.0 (see LICENSE)
19
20
  """
20
21
 
@@ -19,7 +19,8 @@ Usage:
19
19
  python denoise_slice.py -gpus=0 -config=/path/to/config.yaml -slice_number=500
20
20
  (normally launched via denoise_slice.sh)
21
21
 
22
- Author: Cameron Renteria <crentb23@gmail.com>
22
+ Authors: Austin Yunker (Argonne National Laboratory),
23
+ Cameron B. Renteria <crentb23@gmail.com>
23
24
  License: Apache-2.0 (see LICENSE)
24
25
  """
25
26
 
@@ -21,7 +21,8 @@ Usage:
21
21
  python denoise_volume.py -gpus=0 -config=/path/to/config.yaml -start_slice=500 -end_slice=600
22
22
  (normally launched via denoise_volume.sh; omit the range to denoise everything)
23
23
 
24
- Author: Cameron Renteria <crentb23@gmail.com>
24
+ Authors: Austin Yunker (Argonne National Laboratory),
25
+ Cameron B. Renteria <crentb23@gmail.com>
25
26
  License: Apache-2.0 (see LICENSE)
26
27
  """
27
28
 
@@ -8,7 +8,8 @@ flat images (low Laplacian-histogram entropy) it instead rewards smoothness. A
8
8
  higher score means sharper, better-resolved edges, and main.py keeps the
9
9
  checkpoint with the highest score (best_edge_model.pth).
10
10
 
11
- Author: Cameron Renteria <crentb23@gmail.com>
11
+ Authors: Austin Yunker (Argonne National Laboratory),
12
+ Cameron B. Renteria <crentb23@gmail.com>
12
13
  License: Apache-2.0 (see LICENSE)
13
14
  """
14
15
 
@@ -8,7 +8,8 @@ this ratio pushes the network to keep edges sharp (high Laplacian) while smoothi
8
8
  flat regions (low Laplacian), counteracting the over-smoothing that plain L1
9
9
  denoising tends to produce.
10
10
 
11
- Author: Cameron Renteria <crentb23@gmail.com>
11
+ Authors: Austin Yunker (Argonne National Laboratory),
12
+ Cameron B. Renteria <crentb23@gmail.com>
12
13
  License: Apache-2.0 (see LICENSE)
13
14
  """
14
15
 
@@ -15,7 +15,8 @@ setup) and outputs a single denoised slice. Helper modules:
15
15
  unet_up - nearest-neighbour 2x upsampling
16
16
  unet_ns_gn - the full encoder/bottleneck/decoder network
17
17
 
18
- Author: Cameron Renteria <crentb23@gmail.com>
18
+ Authors: Austin Yunker (Argonne National Laboratory),
19
+ Cameron B. Renteria <crentb23@gmail.com>
19
20
  License: Apache-2.0 (see LICENSE)
20
21
  """
21
22
 
@@ -6,7 +6,8 @@ reconstruction: natural (human) sorting of filenames, loading a directory of TIF
6
6
  into a NumPy volume, globbing a directory for TIFFs, saving a volume back out as
7
7
  numbered TIFFs, and loading a stack as a sinogram.
8
8
 
9
- Author: Cameron Renteria <crentb23@gmail.com>
9
+ Authors: Austin Yunker (Argonne National Laboratory),
10
+ Cameron B. Renteria <crentb23@gmail.com>
10
11
  License: Apache-2.0 (see LICENSE)
11
12
  """
12
13
 
@@ -27,7 +27,8 @@ Usage:
27
27
  python main.py -gpus=0 -config=/path/to/config.yaml
28
28
  (normally launched via train.sh)
29
29
 
30
- Author: Cameron Renteria <crentb23@gmail.com>
30
+ Authors: Austin Yunker (Argonne National Laboratory),
31
+ Cameron B. Renteria <crentb23@gmail.com>
31
32
  License: Apache-2.0 (see LICENSE)
32
33
  """
33
34
 
@@ -5,7 +5,8 @@ Helpers shared across the project: write an array to a TIFF or 8-bit PNG preview
5
5
  (`save2img`), save an RGB preview (`save2img_rgb`), rescale an array to uint8
6
6
  (`scale2uint8`), and parse boolean command-line strings (`str2bool`).
7
7
 
8
- Author: Cameron Renteria <crentb23@gmail.com>
8
+ Authors: Austin Yunker (Argonne National Laboratory),
9
+ Cameron B. Renteria <crentb23@gmail.com>
9
10
  License: Apache-2.0 (see LICENSE)
10
11
  """
11
12