seqseg 2.1.6__tar.gz → 2.1.8__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.
- seqseg-2.1.8/PKG-INFO +146 -0
- seqseg-2.1.8/README.md +114 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/pyproject.toml +2 -4
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/cli.py +141 -59
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global.yaml +1 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_cereb.yaml +1 -1
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_debug.yaml +1 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/assembly.py +7 -2
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/nnunet.py +18 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/post.py +53 -34
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/train.py +627 -82
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_cli_helpers.py +195 -11
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_nnunet_device.py +16 -1
- seqseg-2.1.8/seqseg/tests/test_train_data.py +95 -0
- seqseg-2.1.8/seqseg/tests/test_train_pipeline.py +1082 -0
- seqseg-2.1.8/seqseg.egg-info/PKG-INFO +146 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg.egg-info/SOURCES.txt +1 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg.egg-info/requires.txt +1 -3
- seqseg-2.1.6/PKG-INFO +0 -177
- seqseg-2.1.6/README.md +0 -144
- seqseg-2.1.6/seqseg/tests/test_train_pipeline.py +0 -494
- seqseg-2.1.6/seqseg.egg-info/PKG-INFO +0 -177
- {seqseg-2.1.6 → seqseg-2.1.8}/LICENSE +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/__init__.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/api.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/citations.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/__init__.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/aorta_tutorial.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_aorta.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_coro.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_default.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_pulm.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_seg.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config/global_test.yaml +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/config_models.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/__init__.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/capping.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/centerline.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/datasets.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/evaluation.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/initialization.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/local_assembly.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/params.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/prediction.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/simvascular.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/simvascular_contour.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/sitk_functions.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/sweep.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/tracing.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/tracing_functions.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/vmtk_functions.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/modules/vtk_functions.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/parallel/old_auto_centerline.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline2.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline3.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline4.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/__init__.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/classic.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/config.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/directories.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/plus.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/pipeline/single_trace.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/scripts/__init__.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/scripts/prepare_casx_dataset.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/scripts/taubin_smooth.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/seqseg.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/seqseg_plus.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/conftest.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_api_entry.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_centerline_get_end_points.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_centerline_gradient.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_datasets_paths.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_nnunet2.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_prepare_casx_dataset.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_resample_spacing.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_segmentation.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_single_trace_staging.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_start_seg.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_user_paths.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/tests/test_vtk.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg/user_paths.py +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg.egg-info/dependency_links.txt +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg.egg-info/entry_points.txt +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/seqseg.egg-info/top_level.txt +0 -0
- {seqseg-2.1.6 → seqseg-2.1.8}/setup.cfg +0 -0
seqseg-2.1.8/PKG-INFO
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seqseg
|
|
3
|
+
Version: 2.1.8
|
|
4
|
+
Summary: A deep learning-based medical image blood vessel tracking and segmentation tool.
|
|
5
|
+
Author-email: Numi Sveinsson Cepero <numi@berkeley.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: homepage, https://github.com/numisveinsson/SeqSeg
|
|
8
|
+
Project-URL: repository, https://github.com/numisveinsson/SeqSeg
|
|
9
|
+
Keywords: segmentation,deep learning,medical imaging,nnunet,medical image analysis,medical image segmentation,nnU-Net,blood vessel segmentation,vascular segmentation,vascular tracking,seqseg
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Intended Audience :: Healthcare Industry
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Image Recognition
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: vtk>9
|
|
22
|
+
Requires-Dist: SimpleITK>2
|
|
23
|
+
Requires-Dist: PyYAML==6.0.3
|
|
24
|
+
Requires-Dist: nnunetv2>=2.5.1
|
|
25
|
+
Requires-Dist: scipy
|
|
26
|
+
Requires-Dist: vascular-segment-sampler>=0.6.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
29
|
+
Provides-Extra: viz
|
|
30
|
+
Requires-Dist: matplotlib>=3.5; extra == "viz"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/seqseg_logo.png" alt="SeqSeg — Sequential Vessel Segmentation" width="480"/><br/>
|
|
38
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/coronary.png" alt="Example coronary segmentation (SeqSeg)" width="260"/>
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<h1 align="center">SeqSeg: Sequential Vessel Segmentation and Tracking</h1>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<b>Automatic tracking and segmentation of blood vessels in CT and MR images using deep learning and geometric tracking.</b>
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<a href="https://rdcu.be/dU0wy"><img src="https://img.shields.io/badge/Paper-Annals%20of%20BME-blue" alt="Paper"/></a>
|
|
49
|
+
<a href="https://github.com/numisveinsson/SeqSeg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg" alt="License"/></a>
|
|
50
|
+
<a href="https://www.python.org"><img src="https://img.shields.io/badge/Python-3.9%2B-blue.svg" alt="Python 3.9+"/></a>
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
## Why SeqSeg?
|
|
54
|
+
|
|
55
|
+
SeqSeg segments vessels **sequentially**, taking steps along vessel centerlines and detecting bifurcations to grow complete vascular trees from just **1–2 seed points**. By combining local deep-learning predictions (nnU-Net) with geometric tracking, it stays robust across vessel scales — from small coronaries to large aortas.
|
|
56
|
+
|
|
57
|
+
- 🌱 **Minimal supervision** — only 1–2 seed points to initialize
|
|
58
|
+
- 🌿 **Robust bifurcation detection** — automatically follows every branch
|
|
59
|
+
- 🩻 **Multi-modal** — works with CT and MR 3D medical images
|
|
60
|
+
- 📏 **Scalable** — vessels from ~1mm coronaries to ~30mm aortas
|
|
61
|
+
- ✅ **Clinically validated** — coronary, aortic, cerebral, and pulmonary anatomies (pre-trained weights for aorta CT/MR and coronary CT)
|
|
62
|
+
- ⚡ **Fast** — on CPU, about 2–5 minutes for an aorta, 5–15 for a coronary tree, and 10–30 for a cerebral tree. GPU is faster. Details in [Benchmarks](docs/benchmarks.md).
|
|
63
|
+
|
|
64
|
+
A finished case includes a `simvascular/` project you can open directly in SimVascular, with pathlines and contours for every segmented branch.
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/mr_model_tracing_fast_shorter.gif" alt="SeqSeg Demo"/><br/>
|
|
68
|
+
<i>Real-time demonstration: automatic segmentation of an abdominal aorta in a 3D MR scan.</i>
|
|
69
|
+
</p>
|
|
70
|
+
|
|
71
|
+
## Start here
|
|
72
|
+
|
|
73
|
+
- **First segmentation** — the [tutorial](seqseg/tutorial/tutorial.md) runs a sample abdominal-aorta MR scan.
|
|
74
|
+
- **Your own images** — [Usage](docs/usage.md) describes `images/` and `seeds.json`. The command is in [Quick Start](#quick-start).
|
|
75
|
+
- **Train a model** — [Training](docs/training.md).
|
|
76
|
+
|
|
77
|
+
## Quick Start
|
|
78
|
+
|
|
79
|
+
Python 3.9 or newer. 3.11 is the version used in the tutorial and conda example.
|
|
80
|
+
|
|
81
|
+
The [tutorial](seqseg/tutorial/tutorial.md) is the sample run (abdominal-aorta MR, seed points, and Windows notes). Plan on 15–20 minutes including setup. Tracing is capped, so that part finishes in a few minutes; a real case should use the defaults.
|
|
82
|
+
|
|
83
|
+
Install SeqSeg and the aorta weights below, then run `seqseg run batch` on your own data. The folder needs `images/` and `seeds.json` ([Usage](docs/usage.md)). This example is an aorta MR case. Change `-train_dataset`, `-config_name`, and `-img_ext` to match your images and weights.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install seqseg
|
|
87
|
+
|
|
88
|
+
# Aorta and femoral weights (MR and CT)
|
|
89
|
+
curl -L -o nnUNet_results.zip https://zenodo.org/records/15020477/files/nnUNet_results.zip
|
|
90
|
+
unzip nnUNet_results.zip
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
[Aorta and femoral weights](https://zenodo.org/records/15020477) (`nnUNet_results.zip`). [Coronary CT weights](https://zenodo.org/records/19547894) are a separate archive, `nnUNet_results_coronary.zip`.
|
|
94
|
+
|
|
95
|
+
`-nnunet_results_path` is the folder that contains `Dataset005_SEQAORTANDFEMOMR` (and the other dataset folders in that zip).
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
seqseg run batch \
|
|
99
|
+
-data_dir your_data/ \
|
|
100
|
+
-nnunet_results_path nnUNet_results/ \
|
|
101
|
+
-train_dataset Dataset005_SEQAORTANDFEMOMR \
|
|
102
|
+
-config_name global_aorta \
|
|
103
|
+
-img_ext .mha \
|
|
104
|
+
-outdir results/
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| Anatomy | `-train_dataset` | `-config_name` |
|
|
108
|
+
|---------|------------------|----------------|
|
|
109
|
+
| Aorta / femoral MR | `Dataset005_SEQAORTANDFEMOMR` | `global_aorta` |
|
|
110
|
+
| Aorta / femoral CT | `Dataset006_SEQAORTANDFEMOCT` | `global_aorta` |
|
|
111
|
+
| Coronary CT | `Dataset010_SEQCOROASOCACT` | `global_coro` |
|
|
112
|
+
|
|
113
|
+
The tutorial uses `-config_name aorta_tutorial` for its sample scan. The trainer-folder layout is in [Installation](docs/installation.md). The full command list and flag spelling are in [Usage](docs/usage.md).
|
|
114
|
+
|
|
115
|
+
## Documentation
|
|
116
|
+
|
|
117
|
+
| Job | Guide | Description |
|
|
118
|
+
|-----|-------|-------------|
|
|
119
|
+
| Run | [Installation](docs/installation.md) | Setup, dependencies, and pre-trained model weights |
|
|
120
|
+
| Run | [Tutorial](seqseg/tutorial/tutorial.md) | End-to-end aorta example with sample data |
|
|
121
|
+
| Run | [Usage](docs/usage.md) | Data layout, seeds, CLI arguments, and output files |
|
|
122
|
+
| Run | [Configuration](docs/configuration.md) | YAML configs and tracking parameters |
|
|
123
|
+
| Train | [Training](docs/training.md) | Train nnU-Net models on a new dataset |
|
|
124
|
+
| Understand | [Algorithm Overview](docs/algorithm.md) | Methodology, workflow, and training strategy |
|
|
125
|
+
| Understand | [Performance & Benchmarks](docs/benchmarks.md) | Accuracy, timing, and qualitative comparisons |
|
|
126
|
+
| Integrate | [API](docs/api.md) | Call tracing from Python |
|
|
127
|
+
| Integrate | [Research & Development](docs/development.md) | SimVascular, 3D Slicer, and repository layout |
|
|
128
|
+
|
|
129
|
+
## Citation
|
|
130
|
+
|
|
131
|
+
When using SeqSeg, please cite the following [paper](https://rdcu.be/dU0wy):
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
@Article{SveinssonCepero2024,
|
|
135
|
+
author={Sveinsson Cepero, Numi
|
|
136
|
+
and Shadden, Shawn C.},
|
|
137
|
+
title={SeqSeg: Learning Local Segments for Automatic Vascular Model Construction},
|
|
138
|
+
journal={Annals of Biomedical Engineering},
|
|
139
|
+
year={2024},
|
|
140
|
+
month={Sep},
|
|
141
|
+
day={18},
|
|
142
|
+
issn={1573-9686},
|
|
143
|
+
doi={10.1007/s10439-024-03611-z},
|
|
144
|
+
url={https://doi.org/10.1007/s10439-024-03611-z},
|
|
145
|
+
}
|
|
146
|
+
```
|
seqseg-2.1.8/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+

|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/seqseg_logo.png" alt="SeqSeg — Sequential Vessel Segmentation" width="480"/><br/>
|
|
6
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/coronary.png" alt="Example coronary segmentation (SeqSeg)" width="260"/>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<h1 align="center">SeqSeg: Sequential Vessel Segmentation and Tracking</h1>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<b>Automatic tracking and segmentation of blood vessels in CT and MR images using deep learning and geometric tracking.</b>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://rdcu.be/dU0wy"><img src="https://img.shields.io/badge/Paper-Annals%20of%20BME-blue" alt="Paper"/></a>
|
|
17
|
+
<a href="https://github.com/numisveinsson/SeqSeg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg" alt="License"/></a>
|
|
18
|
+
<a href="https://www.python.org"><img src="https://img.shields.io/badge/Python-3.9%2B-blue.svg" alt="Python 3.9+"/></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
## Why SeqSeg?
|
|
22
|
+
|
|
23
|
+
SeqSeg segments vessels **sequentially**, taking steps along vessel centerlines and detecting bifurcations to grow complete vascular trees from just **1–2 seed points**. By combining local deep-learning predictions (nnU-Net) with geometric tracking, it stays robust across vessel scales — from small coronaries to large aortas.
|
|
24
|
+
|
|
25
|
+
- 🌱 **Minimal supervision** — only 1–2 seed points to initialize
|
|
26
|
+
- 🌿 **Robust bifurcation detection** — automatically follows every branch
|
|
27
|
+
- 🩻 **Multi-modal** — works with CT and MR 3D medical images
|
|
28
|
+
- 📏 **Scalable** — vessels from ~1mm coronaries to ~30mm aortas
|
|
29
|
+
- ✅ **Clinically validated** — coronary, aortic, cerebral, and pulmonary anatomies (pre-trained weights for aorta CT/MR and coronary CT)
|
|
30
|
+
- ⚡ **Fast** — on CPU, about 2–5 minutes for an aorta, 5–15 for a coronary tree, and 10–30 for a cerebral tree. GPU is faster. Details in [Benchmarks](docs/benchmarks.md).
|
|
31
|
+
|
|
32
|
+
A finished case includes a `simvascular/` project you can open directly in SimVascular, with pathlines and contours for every segmented branch.
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/mr_model_tracing_fast_shorter.gif" alt="SeqSeg Demo"/><br/>
|
|
36
|
+
<i>Real-time demonstration: automatic segmentation of an abdominal aorta in a 3D MR scan.</i>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
## Start here
|
|
40
|
+
|
|
41
|
+
- **First segmentation** — the [tutorial](seqseg/tutorial/tutorial.md) runs a sample abdominal-aorta MR scan.
|
|
42
|
+
- **Your own images** — [Usage](docs/usage.md) describes `images/` and `seeds.json`. The command is in [Quick Start](#quick-start).
|
|
43
|
+
- **Train a model** — [Training](docs/training.md).
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
Python 3.9 or newer. 3.11 is the version used in the tutorial and conda example.
|
|
48
|
+
|
|
49
|
+
The [tutorial](seqseg/tutorial/tutorial.md) is the sample run (abdominal-aorta MR, seed points, and Windows notes). Plan on 15–20 minutes including setup. Tracing is capped, so that part finishes in a few minutes; a real case should use the defaults.
|
|
50
|
+
|
|
51
|
+
Install SeqSeg and the aorta weights below, then run `seqseg run batch` on your own data. The folder needs `images/` and `seeds.json` ([Usage](docs/usage.md)). This example is an aorta MR case. Change `-train_dataset`, `-config_name`, and `-img_ext` to match your images and weights.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install seqseg
|
|
55
|
+
|
|
56
|
+
# Aorta and femoral weights (MR and CT)
|
|
57
|
+
curl -L -o nnUNet_results.zip https://zenodo.org/records/15020477/files/nnUNet_results.zip
|
|
58
|
+
unzip nnUNet_results.zip
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
[Aorta and femoral weights](https://zenodo.org/records/15020477) (`nnUNet_results.zip`). [Coronary CT weights](https://zenodo.org/records/19547894) are a separate archive, `nnUNet_results_coronary.zip`.
|
|
62
|
+
|
|
63
|
+
`-nnunet_results_path` is the folder that contains `Dataset005_SEQAORTANDFEMOMR` (and the other dataset folders in that zip).
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
seqseg run batch \
|
|
67
|
+
-data_dir your_data/ \
|
|
68
|
+
-nnunet_results_path nnUNet_results/ \
|
|
69
|
+
-train_dataset Dataset005_SEQAORTANDFEMOMR \
|
|
70
|
+
-config_name global_aorta \
|
|
71
|
+
-img_ext .mha \
|
|
72
|
+
-outdir results/
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| Anatomy | `-train_dataset` | `-config_name` |
|
|
76
|
+
|---------|------------------|----------------|
|
|
77
|
+
| Aorta / femoral MR | `Dataset005_SEQAORTANDFEMOMR` | `global_aorta` |
|
|
78
|
+
| Aorta / femoral CT | `Dataset006_SEQAORTANDFEMOCT` | `global_aorta` |
|
|
79
|
+
| Coronary CT | `Dataset010_SEQCOROASOCACT` | `global_coro` |
|
|
80
|
+
|
|
81
|
+
The tutorial uses `-config_name aorta_tutorial` for its sample scan. The trainer-folder layout is in [Installation](docs/installation.md). The full command list and flag spelling are in [Usage](docs/usage.md).
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
| Job | Guide | Description |
|
|
86
|
+
|-----|-------|-------------|
|
|
87
|
+
| Run | [Installation](docs/installation.md) | Setup, dependencies, and pre-trained model weights |
|
|
88
|
+
| Run | [Tutorial](seqseg/tutorial/tutorial.md) | End-to-end aorta example with sample data |
|
|
89
|
+
| Run | [Usage](docs/usage.md) | Data layout, seeds, CLI arguments, and output files |
|
|
90
|
+
| Run | [Configuration](docs/configuration.md) | YAML configs and tracking parameters |
|
|
91
|
+
| Train | [Training](docs/training.md) | Train nnU-Net models on a new dataset |
|
|
92
|
+
| Understand | [Algorithm Overview](docs/algorithm.md) | Methodology, workflow, and training strategy |
|
|
93
|
+
| Understand | [Performance & Benchmarks](docs/benchmarks.md) | Accuracy, timing, and qualitative comparisons |
|
|
94
|
+
| Integrate | [API](docs/api.md) | Call tracing from Python |
|
|
95
|
+
| Integrate | [Research & Development](docs/development.md) | SimVascular, 3D Slicer, and repository layout |
|
|
96
|
+
|
|
97
|
+
## Citation
|
|
98
|
+
|
|
99
|
+
When using SeqSeg, please cite the following [paper](https://rdcu.be/dU0wy):
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
@Article{SveinssonCepero2024,
|
|
103
|
+
author={Sveinsson Cepero, Numi
|
|
104
|
+
and Shadden, Shawn C.},
|
|
105
|
+
title={SeqSeg: Learning Local Segments for Automatic Vascular Model Construction},
|
|
106
|
+
journal={Annals of Biomedical Engineering},
|
|
107
|
+
year={2024},
|
|
108
|
+
month={Sep},
|
|
109
|
+
day={18},
|
|
110
|
+
issn={1573-9686},
|
|
111
|
+
doi={10.1007/s10439-024-03611-z},
|
|
112
|
+
url={https://doi.org/10.1007/s10439-024-03611-z},
|
|
113
|
+
}
|
|
114
|
+
```
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "seqseg"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.8"
|
|
8
8
|
description = "A deep learning-based medical image blood vessel tracking and segmentation tool."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -42,6 +42,7 @@ dependencies = [
|
|
|
42
42
|
"PyYAML==6.0.3",
|
|
43
43
|
"nnunetv2>=2.5.1",
|
|
44
44
|
"scipy",
|
|
45
|
+
"vascular-segment-sampler>=0.6.0",
|
|
45
46
|
]
|
|
46
47
|
|
|
47
48
|
[project.scripts]
|
|
@@ -62,9 +63,6 @@ dev = [
|
|
|
62
63
|
viz = [
|
|
63
64
|
"matplotlib>=3.5",
|
|
64
65
|
]
|
|
65
|
-
train = [
|
|
66
|
-
"vascular-segment-sampler>=0.1.0",
|
|
67
|
-
]
|
|
68
66
|
|
|
69
67
|
[tool.pytest.ini_options]
|
|
70
68
|
testpaths = ["seqseg/tests"]
|
|
@@ -225,7 +225,8 @@ def _validate_trace_batch(ns: argparse.Namespace) -> None:
|
|
|
225
225
|
+ "\n ".join(missing)
|
|
226
226
|
+ "\n\nMinimal example:\n"
|
|
227
227
|
" seqseg paths init\n"
|
|
228
|
-
" seqseg paths set --
|
|
228
|
+
" seqseg paths set --nnunet-root ~/nnunet_data "
|
|
229
|
+
"--data-dir /path/to/dataset --outdir /path/to/out\n"
|
|
229
230
|
" seqseg run batch -img_ext .nii.gz "
|
|
230
231
|
"-train_dataset Dataset010_SEQCOROASOCACT\n",
|
|
231
232
|
file=sys.stderr,
|
|
@@ -435,9 +436,8 @@ def _cmd_init_dataset(ns: argparse.Namespace) -> None:
|
|
|
435
436
|
f" seqseg run batch -data_dir {root}/ -outdir ... -img_ext .nii.gz "
|
|
436
437
|
"-nnunet_results_path ...\n"
|
|
437
438
|
"\nNext (train a new model): also fill centerlines/ and truths/, then:\n"
|
|
438
|
-
f' pip install "seqseg[train]"\n'
|
|
439
439
|
f" seqseg paths init --data-dir {root}/ --outdir ~/seqseg_train\n"
|
|
440
|
-
" seqseg train prepare --name MYDATA --dataset-
|
|
440
|
+
" seqseg train prepare --name MYDATA --dataset-id 999 --modality CT\n"
|
|
441
441
|
)
|
|
442
442
|
|
|
443
443
|
|
|
@@ -550,10 +550,7 @@ def _cmd_doctor(ns: argparse.Namespace) -> None:
|
|
|
550
550
|
try:
|
|
551
551
|
importlib.import_module(modname)
|
|
552
552
|
except ImportError as e:
|
|
553
|
-
|
|
554
|
-
if modname == "vascular_segment_sampler":
|
|
555
|
-
extra = ' — optional; pip install "seqseg[train]"'
|
|
556
|
-
print(f" {label}: MISSING ({e}){extra}")
|
|
553
|
+
print(f" {label}: MISSING ({e})")
|
|
557
554
|
else:
|
|
558
555
|
print(f" {label}: OK")
|
|
559
556
|
|
|
@@ -592,19 +589,9 @@ def _cmd_paths_init(ns: argparse.Namespace) -> None:
|
|
|
592
589
|
|
|
593
590
|
|
|
594
591
|
def _cmd_paths_set(ns: argparse.Namespace) -> None:
|
|
595
|
-
|
|
596
|
-
ns.nnunet_root,
|
|
597
|
-
ns.nnunet_raw,
|
|
598
|
-
ns.nnunet_preprocessed,
|
|
599
|
-
ns.nnunet_results,
|
|
600
|
-
ns.data_dir,
|
|
601
|
-
ns.outdir,
|
|
602
|
-
)
|
|
603
|
-
if not any(f is not None for f in fields):
|
|
592
|
+
if not ns.nnunet_root:
|
|
604
593
|
print(
|
|
605
|
-
"seqseg paths set:
|
|
606
|
-
"--nnunet-root, --nnunet-raw, --nnunet-preprocessed, "
|
|
607
|
-
"--nnunet-results, --data-dir, --outdir",
|
|
594
|
+
"seqseg paths set: --nnunet-root is required",
|
|
608
595
|
file=sys.stderr,
|
|
609
596
|
)
|
|
610
597
|
sys.exit(2)
|
|
@@ -647,6 +634,12 @@ def _cmd_paths_export(_ns: argparse.Namespace) -> None:
|
|
|
647
634
|
|
|
648
635
|
|
|
649
636
|
def _cmd_train_prepare(ns: argparse.Namespace) -> None:
|
|
637
|
+
if not ns.preprocess_only and not ns.name:
|
|
638
|
+
print(
|
|
639
|
+
"seqseg train prepare: --name is required",
|
|
640
|
+
file=sys.stderr,
|
|
641
|
+
)
|
|
642
|
+
sys.exit(2)
|
|
650
643
|
try:
|
|
651
644
|
result = prepare_training_dataset(
|
|
652
645
|
data_dir=ns.data_dir,
|
|
@@ -669,14 +662,31 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
|
|
|
669
662
|
skip_sample=ns.skip_sample,
|
|
670
663
|
skip_convert=ns.skip_convert,
|
|
671
664
|
also_test=ns.also_test,
|
|
672
|
-
yes=ns.yes,
|
|
673
665
|
verbose=ns.verbose,
|
|
674
666
|
img_ext=ns.img_ext,
|
|
675
667
|
global_volumes=ns.global_volumes,
|
|
668
|
+
keep_extracted=ns.keep_extracted,
|
|
669
|
+
configuration=ns.configuration,
|
|
670
|
+
plans=ns.plans,
|
|
671
|
+
np=ns.np,
|
|
672
|
+
preprocess_only=ns.preprocess_only,
|
|
676
673
|
)
|
|
677
674
|
except TrainDependencyError as e:
|
|
678
675
|
print(str(e), file=sys.stderr)
|
|
679
676
|
sys.exit(1)
|
|
677
|
+
except FileNotFoundError as e:
|
|
678
|
+
message = str(e)
|
|
679
|
+
if message.startswith("Sampler config"):
|
|
680
|
+
print(message, file=sys.stderr)
|
|
681
|
+
sys.exit(2)
|
|
682
|
+
if "seqseg train prepare" in message:
|
|
683
|
+
print(message, file=sys.stderr)
|
|
684
|
+
sys.exit(1)
|
|
685
|
+
import traceback
|
|
686
|
+
|
|
687
|
+
traceback.print_exc()
|
|
688
|
+
print(f"seqseg train prepare failed: {e}", file=sys.stderr)
|
|
689
|
+
sys.exit(1)
|
|
680
690
|
except Exception as e: # noqa: BLE001
|
|
681
691
|
import traceback
|
|
682
692
|
|
|
@@ -693,8 +703,29 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
|
|
|
693
703
|
sys.exit(1)
|
|
694
704
|
|
|
695
705
|
print("\nPrepare complete.")
|
|
696
|
-
|
|
697
|
-
|
|
706
|
+
if ns.preprocess_only:
|
|
707
|
+
print(
|
|
708
|
+
f" Preprocessed {ns.configuration} from the existing raw dataset."
|
|
709
|
+
)
|
|
710
|
+
elif result.removed_staging:
|
|
711
|
+
print(
|
|
712
|
+
" Extracted volumes were linked into nnU-Net raw and the "
|
|
713
|
+
"temporary folder was removed."
|
|
714
|
+
)
|
|
715
|
+
else:
|
|
716
|
+
kind = "Whole volumes" if ns.global_volumes else "Patches"
|
|
717
|
+
print(f" {kind}: {result.extracted_dir}")
|
|
718
|
+
if not result.preprocessed:
|
|
719
|
+
print(
|
|
720
|
+
" nnU-Net preprocessing was skipped (--skip-convert). "
|
|
721
|
+
"Re-run prepare without --skip-convert before training."
|
|
722
|
+
)
|
|
723
|
+
results = resolve_path("nnunet_results")
|
|
724
|
+
if results:
|
|
725
|
+
print(f" Trained models will be written under: {results}")
|
|
726
|
+
config_flag = ""
|
|
727
|
+
if ns.configuration != "3d_fullres":
|
|
728
|
+
config_flag = f" --configuration {ns.configuration}"
|
|
698
729
|
for name, path in zip(result.dataset_names, result.dataset_dirs):
|
|
699
730
|
try:
|
|
700
731
|
ds_id = dataset_id_from_name(name)
|
|
@@ -702,11 +733,12 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
|
|
|
702
733
|
ds_id = "?"
|
|
703
734
|
print(f" nnU-Net dataset: {name}")
|
|
704
735
|
print(f" path: {path}")
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
736
|
+
if result.preprocessed:
|
|
737
|
+
print(
|
|
738
|
+
" next:\n"
|
|
739
|
+
f" seqseg train nnunet --dataset-id {ds_id}"
|
|
740
|
+
f"{config_flag} --fold 0"
|
|
741
|
+
)
|
|
710
742
|
|
|
711
743
|
|
|
712
744
|
def _cmd_train_nnunet(ns: argparse.Namespace) -> None:
|
|
@@ -729,11 +761,10 @@ def _cmd_train_nnunet(ns: argparse.Namespace) -> None:
|
|
|
729
761
|
dataset_id,
|
|
730
762
|
configuration=ns.configuration,
|
|
731
763
|
fold=ns.fold,
|
|
732
|
-
skip_plan=ns.skip_plan,
|
|
733
|
-
plan_only=ns.plan_only,
|
|
734
|
-
np=ns.np,
|
|
735
764
|
trainer=ns.trainer,
|
|
736
765
|
plans=ns.plans,
|
|
766
|
+
cleanup=ns.cleanup,
|
|
767
|
+
continue_training=ns.continue_training,
|
|
737
768
|
)
|
|
738
769
|
except Exception as e: # noqa: BLE001
|
|
739
770
|
print(f"seqseg train nnunet failed: {e}", file=sys.stderr)
|
|
@@ -921,8 +952,18 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
921
952
|
g1 = gcl_sub.add_parser("single", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
922
953
|
g1.add_argument("--seg", required=True, type=str)
|
|
923
954
|
g1.add_argument("--out", required=True, type=str)
|
|
924
|
-
g1.add_argument(
|
|
925
|
-
|
|
955
|
+
g1.add_argument(
|
|
956
|
+
"--seeds-json",
|
|
957
|
+
default=None,
|
|
958
|
+
type=str,
|
|
959
|
+
help="Dataset seeds.json. Omit to place one seed in each disconnected body",
|
|
960
|
+
)
|
|
961
|
+
g1.add_argument(
|
|
962
|
+
"--case-name",
|
|
963
|
+
default=None,
|
|
964
|
+
type=str,
|
|
965
|
+
help="Case name in seeds.json. Required when --seeds-json is set",
|
|
966
|
+
)
|
|
926
967
|
g1.add_argument("--config-name", default=None, type=str)
|
|
927
968
|
g1.add_argument("--merge-method", default="clean", type=str)
|
|
928
969
|
g1.add_argument("--directory-data", default=None, type=str)
|
|
@@ -932,7 +973,12 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
932
973
|
g2 = gcl_sub.add_parser("batch", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
933
974
|
g2.add_argument("--seg-dir", required=True, type=str)
|
|
934
975
|
g2.add_argument("--seg-glob", required=True, type=str)
|
|
935
|
-
g2.add_argument(
|
|
976
|
+
g2.add_argument(
|
|
977
|
+
"--seeds-json",
|
|
978
|
+
default=None,
|
|
979
|
+
type=str,
|
|
980
|
+
help="Dataset seeds.json. Omit to place one seed in each disconnected body",
|
|
981
|
+
)
|
|
936
982
|
g2.add_argument("--out-dir", default=None, type=str)
|
|
937
983
|
g2.add_argument("--config-name", default=None, type=str)
|
|
938
984
|
g2.add_argument("--merge-method", default="clean", type=str)
|
|
@@ -998,7 +1044,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
998
1044
|
|
|
999
1045
|
p_prep = train_sub.add_parser(
|
|
1000
1046
|
"prepare",
|
|
1001
|
-
help="
|
|
1047
|
+
help="Extract volumes, write an nnU-Net dataset, and plan/preprocess",
|
|
1002
1048
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
1003
1049
|
)
|
|
1004
1050
|
p_prep.add_argument(
|
|
@@ -1014,22 +1060,27 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1014
1060
|
"-outdir",
|
|
1015
1061
|
default=None,
|
|
1016
1062
|
type=str,
|
|
1017
|
-
help="
|
|
1018
|
-
"
|
|
1063
|
+
help="Optional scratch directory for extracted patches or whole volumes. "
|
|
1064
|
+
"Default: <parent of nnUNet_raw>/_seqseg_extracted, removed after "
|
|
1065
|
+
"conversion. Pass this to keep extracts or resume with --skip-sample.",
|
|
1019
1066
|
)
|
|
1020
1067
|
p_prep.add_argument(
|
|
1021
1068
|
"--name",
|
|
1022
1069
|
"-name",
|
|
1023
|
-
|
|
1070
|
+
default=None,
|
|
1024
1071
|
type=str,
|
|
1025
|
-
help="Dataset name stem (e.g. MYDATA → Dataset0XX_MYDATACT)"
|
|
1072
|
+
help="Dataset name stem (e.g. MYDATA → Dataset0XX_MYDATACT). "
|
|
1073
|
+
"Required unless --preprocess-only",
|
|
1026
1074
|
)
|
|
1027
1075
|
p_prep.add_argument(
|
|
1076
|
+
"--dataset-id",
|
|
1028
1077
|
"--dataset-number",
|
|
1029
1078
|
"-dataset_number",
|
|
1079
|
+
dest="dataset_number",
|
|
1030
1080
|
required=True,
|
|
1031
1081
|
type=int,
|
|
1032
|
-
help="nnU-Net dataset id (e.g. 999).
|
|
1082
|
+
help="nnU-Net dataset id to create (e.g. 999). "
|
|
1083
|
+
"Incremented per modality if several",
|
|
1033
1084
|
)
|
|
1034
1085
|
p_prep.add_argument(
|
|
1035
1086
|
"--modality",
|
|
@@ -1041,7 +1092,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1041
1092
|
p_prep.add_argument(
|
|
1042
1093
|
"--config-name",
|
|
1043
1094
|
"-config_name",
|
|
1044
|
-
default="
|
|
1095
|
+
default="default_mm",
|
|
1045
1096
|
type=str,
|
|
1046
1097
|
help="Sampler YAML name/path (from vascular-segment-sampler)",
|
|
1047
1098
|
)
|
|
@@ -1050,7 +1101,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1050
1101
|
default=None,
|
|
1051
1102
|
type=str,
|
|
1052
1103
|
help="Write DatasetXXX_* here "
|
|
1053
|
-
"(default: seqseg paths nnunet_raw / $nnUNet_raw
|
|
1104
|
+
"(default: seqseg paths nnunet_raw / $nnUNet_raw)",
|
|
1054
1105
|
)
|
|
1055
1106
|
p_prep.add_argument(
|
|
1056
1107
|
"--img-ext",
|
|
@@ -1101,13 +1152,41 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1101
1152
|
action="store_true",
|
|
1102
1153
|
help="Also convert modality_test folders when present",
|
|
1103
1154
|
)
|
|
1104
|
-
p_prep.add_argument("--yes", action="store_true", help="Non-interactive confirms")
|
|
1105
1155
|
p_prep.add_argument("--verbose", action="store_true")
|
|
1156
|
+
p_prep.add_argument(
|
|
1157
|
+
"--keep-extracted",
|
|
1158
|
+
action="store_true",
|
|
1159
|
+
help="Keep <nnunet-root>/_seqseg_extracted after conversion into nnUNet_raw",
|
|
1160
|
+
)
|
|
1161
|
+
p_prep.add_argument(
|
|
1162
|
+
"--configuration",
|
|
1163
|
+
default="3d_fullres",
|
|
1164
|
+
choices=["3d_fullres", "2d", "3d_lowres", "3d_cascade_fullres"],
|
|
1165
|
+
help="nnU-Net configuration to preprocess. Default 3d_fullres",
|
|
1166
|
+
)
|
|
1167
|
+
p_prep.add_argument(
|
|
1168
|
+
"--plans",
|
|
1169
|
+
default="nnUNetPlans",
|
|
1170
|
+
type=str,
|
|
1171
|
+
help="nnU-Net plans name (training -p). Default nnUNetPlans",
|
|
1172
|
+
)
|
|
1173
|
+
p_prep.add_argument(
|
|
1174
|
+
"--np",
|
|
1175
|
+
type=int,
|
|
1176
|
+
default=None,
|
|
1177
|
+
help="Processes for nnU-Net preprocessing. Default: --num-cores",
|
|
1178
|
+
)
|
|
1179
|
+
p_prep.add_argument(
|
|
1180
|
+
"--preprocess-only",
|
|
1181
|
+
action="store_true",
|
|
1182
|
+
help="Preprocess another configuration from an existing raw dataset "
|
|
1183
|
+
"and plans file. Does not extract or convert subvolumes",
|
|
1184
|
+
)
|
|
1106
1185
|
p_prep.set_defaults(_handler=_cmd_train_prepare, img_ext=None)
|
|
1107
1186
|
|
|
1108
1187
|
p_nn = train_sub.add_parser(
|
|
1109
1188
|
"nnunet",
|
|
1110
|
-
help="
|
|
1189
|
+
help="Train with nnUNetv2_train (--c continues from the latest checkpoint)",
|
|
1111
1190
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
1112
1191
|
)
|
|
1113
1192
|
p_nn.add_argument(
|
|
@@ -1120,13 +1199,13 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1120
1199
|
"--dataset-name",
|
|
1121
1200
|
type=str,
|
|
1122
1201
|
default=None,
|
|
1123
|
-
help="Alternative to --dataset-id (e.g.
|
|
1202
|
+
help="Alternative to --dataset-id (e.g. Dataset999_MYDATACT)",
|
|
1124
1203
|
)
|
|
1125
1204
|
p_nn.add_argument(
|
|
1126
1205
|
"--configuration",
|
|
1127
1206
|
default="3d_fullres",
|
|
1128
1207
|
choices=["3d_fullres", "2d", "3d_lowres", "3d_cascade_fullres"],
|
|
1129
|
-
help="nnU-Net configuration
|
|
1208
|
+
help="nnU-Net configuration to train. Default 3d_fullres",
|
|
1130
1209
|
)
|
|
1131
1210
|
p_nn.add_argument(
|
|
1132
1211
|
"--fold",
|
|
@@ -1135,23 +1214,21 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1135
1214
|
help="Fold to train (0-4 or all)",
|
|
1136
1215
|
)
|
|
1137
1216
|
p_nn.add_argument(
|
|
1138
|
-
"--
|
|
1217
|
+
"--c",
|
|
1218
|
+
"--continue",
|
|
1219
|
+
dest="continue_training",
|
|
1139
1220
|
action="store_true",
|
|
1140
|
-
help="
|
|
1221
|
+
help="Continue training from checkpoint_latest.pth (nnU-Net --c)",
|
|
1141
1222
|
)
|
|
1223
|
+
p_nn.add_argument("--trainer", default="nnUNetTrainer", type=str)
|
|
1224
|
+
p_nn.add_argument("--plans", default="nnUNetPlans", type=str)
|
|
1142
1225
|
p_nn.add_argument(
|
|
1143
|
-
"--
|
|
1226
|
+
"--cleanup",
|
|
1144
1227
|
action="store_true",
|
|
1145
|
-
help="
|
|
1228
|
+
help="After training succeeds, delete this dataset's nnUNet_raw and "
|
|
1229
|
+
"nnUNet_preprocessed folders. Leaves nnUNet_results. "
|
|
1230
|
+
"A later --c run needs that preprocessed data.",
|
|
1146
1231
|
)
|
|
1147
|
-
p_nn.add_argument(
|
|
1148
|
-
"--np",
|
|
1149
|
-
type=int,
|
|
1150
|
-
default=None,
|
|
1151
|
-
help="Processes for plan_and_preprocess (-np)",
|
|
1152
|
-
)
|
|
1153
|
-
p_nn.add_argument("--trainer", default="nnUNetTrainer", type=str)
|
|
1154
|
-
p_nn.add_argument("--plans", default="nnUNetPlans", type=str)
|
|
1155
1232
|
p_nn.set_defaults(_handler=_cmd_train_nnunet)
|
|
1156
1233
|
|
|
1157
1234
|
paths_p = sub.add_parser(
|
|
@@ -1194,10 +1271,15 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1194
1271
|
|
|
1195
1272
|
p_set = paths_sub.add_parser(
|
|
1196
1273
|
"set",
|
|
1197
|
-
help="Update
|
|
1274
|
+
help="Update saved paths (requires --nnunet-root)",
|
|
1198
1275
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
1199
1276
|
)
|
|
1200
|
-
p_set.add_argument(
|
|
1277
|
+
p_set.add_argument(
|
|
1278
|
+
"--nnunet-root",
|
|
1279
|
+
required=True,
|
|
1280
|
+
type=str,
|
|
1281
|
+
help="Parent directory for nnUNet_raw / preprocessed / results",
|
|
1282
|
+
)
|
|
1201
1283
|
p_set.add_argument("--nnunet-raw", default=None, type=str)
|
|
1202
1284
|
p_set.add_argument("--nnunet-preprocessed", default=None, type=str)
|
|
1203
1285
|
p_set.add_argument("--nnunet-results", default=None, type=str)
|
|
@@ -14,6 +14,7 @@ TREE_ANALYSIS: False
|
|
|
14
14
|
|
|
15
15
|
VOLUME_SIZE_RATIO: 5 # default 5, 5.5 for coronaries, 4 for segs
|
|
16
16
|
MAGN_RADIUS: 1
|
|
17
|
+
ADD_RADIUS: 0 # mm (keep in mm)
|
|
17
18
|
MAX_PERC_ENLARGE: 0.3 # if percent of blood in a given volume goes above this, we try enlarging volume, default 0.33 for coronaries
|
|
18
19
|
MIN_RADIUS: 0.3 # mm (keep in mm)
|
|
19
20
|
MIN_RES: 6
|