tomo-image-stitcher 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tomo_image_stitcher-0.2.0/LICENSE +21 -0
- tomo_image_stitcher-0.2.0/PKG-INFO +254 -0
- tomo_image_stitcher-0.2.0/README.md +180 -0
- tomo_image_stitcher-0.2.0/pyproject.toml +96 -0
- tomo_image_stitcher-0.2.0/setup.cfg +4 -0
- tomo_image_stitcher-0.2.0/setup.py +5 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/__init__.py +32 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/danmax.py +1200 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/py.typed +1 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/registration.py +697 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/stitcher.py +2503 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher/transform.py +313 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher.egg-info/PKG-INFO +254 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher.egg-info/SOURCES.txt +18 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher.egg-info/dependency_links.txt +1 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher.egg-info/requires.txt +33 -0
- tomo_image_stitcher-0.2.0/src/tomo_image_stitcher.egg-info/top_level.txt +1 -0
- tomo_image_stitcher-0.2.0/tests/test_stitcher.py +65 -0
- tomo_image_stitcher-0.2.0/tests/test_transform.py +37 -0
- tomo_image_stitcher-0.2.0/tests/test_utilities.py +99 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Endri Lacaj, Indrajeet Tambe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tomo-image-stitcher
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: GPU-accelerated 3D volumetric stitcher for tomographic and microscopy volumes.
|
|
5
|
+
Author: Endri Lacaj, Indrajeet Tambe
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) Endri Lacaj, Indrajeet Tambe
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/indrajeettambe/TomoImageStitcher
|
|
29
|
+
Project-URL: Issues, https://github.com/indrajeettambe/TomoImageStitcher/issues
|
|
30
|
+
Project-URL: Documentation, https://github.com/indrajeettambe/TomoImageStitcher/tree/main/docs
|
|
31
|
+
Keywords: stitching,tomography,registration,GPU,CuPy,volume-stitching,3D
|
|
32
|
+
Classifier: Development Status :: 4 - Beta
|
|
33
|
+
Classifier: Intended Audience :: Science/Research
|
|
34
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
35
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
41
|
+
Classifier: Topic :: Scientific/Engineering
|
|
42
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
43
|
+
Requires-Python: >=3.9
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
License-File: LICENSE
|
|
46
|
+
Requires-Dist: numpy>=1.23
|
|
47
|
+
Requires-Dist: scipy>=1.10
|
|
48
|
+
Requires-Dist: scikit-learn>=1.2
|
|
49
|
+
Requires-Dist: h5py>=3.8
|
|
50
|
+
Requires-Dist: tifffile>=2023.4
|
|
51
|
+
Requires-Dist: imagecodecs>=2023.1
|
|
52
|
+
Requires-Dist: SimpleITK>=2.3
|
|
53
|
+
Requires-Dist: scikit-image>=0.20
|
|
54
|
+
Requires-Dist: matplotlib>=3.7
|
|
55
|
+
Requires-Dist: tqdm>=4.65
|
|
56
|
+
Requires-Dist: cupy-cuda12x>=13.0; sys_platform != "darwin"
|
|
57
|
+
Provides-Extra: danmax
|
|
58
|
+
Requires-Dist: ipywidgets>=8.0; extra == "danmax"
|
|
59
|
+
Requires-Dist: pyFAI>=2023.1; extra == "danmax"
|
|
60
|
+
Requires-Dist: pytz>=2023.3; extra == "danmax"
|
|
61
|
+
Provides-Extra: notebook
|
|
62
|
+
Requires-Dist: jupyter>=1.0; extra == "notebook"
|
|
63
|
+
Requires-Dist: ipykernel>=6.0; extra == "notebook"
|
|
64
|
+
Requires-Dist: notebook>=7.0; extra == "notebook"
|
|
65
|
+
Provides-Extra: dev
|
|
66
|
+
Requires-Dist: pytest>=7.3; extra == "dev"
|
|
67
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
68
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
69
|
+
Requires-Dist: flake8>=6.0; extra == "dev"
|
|
70
|
+
Requires-Dist: isort>=5.12; extra == "dev"
|
|
71
|
+
Provides-Extra: all
|
|
72
|
+
Requires-Dist: tomo-image-stitcher[danmax,dev,notebook]; extra == "all"
|
|
73
|
+
Dynamic: license-file
|
|
74
|
+
|
|
75
|
+
# TomoImageStitcher
|
|
76
|
+
|
|
77
|
+
[](https://www.python.org/downloads/)
|
|
78
|
+
[](LICENSE)
|
|
79
|
+
[](https://github.com/psf/black)
|
|
80
|
+
[](https://cupy.dev/)
|
|
81
|
+
|
|
82
|
+
A GPU-accelerated, sub-pixel accurate **3D volumetric stitcher** for tomographic and
|
|
83
|
+
large-volume microscopy datasets. TomoImageStitcher registers overlapping 3D
|
|
84
|
+
sub-volumes acquired on a translation (and optionally rotation) stage and produces
|
|
85
|
+
a single seamless volume with mask-aware blending and optional intensity
|
|
86
|
+
equalisation.
|
|
87
|
+
|
|
88
|
+
> Originally developed for stitching local X-ray tomography volumes for the Experiment at the **DanMAX** beamline, Sweden.
|
|
89
|
+
|
|
90
|
+
For a **detailed step-by-step walkthrough** of every pipeline stage with synthetic
|
|
91
|
+
data, see [`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb).
|
|
92
|
+
For the mathematical details of the registration, see **[PUBLICATION]**.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## What is it
|
|
97
|
+
|
|
98
|
+
TomoImageStitcher stitches together a set of **overlapping 3D sub-volumes**
|
|
99
|
+
(typically reconstructed tomography volumes) into **one seamless volume**.
|
|
100
|
+
Each stage is a Python call on the `Stitcher` object, so you can inspect and
|
|
101
|
+
re-run any stage on its own.
|
|
102
|
+
|
|
103
|
+
The pipeline runs in **six stages**:
|
|
104
|
+
|
|
105
|
+
| # | Stage | What it does |
|
|
106
|
+
|---|-------|--------------|
|
|
107
|
+
| 1 | **Organise sub-volumes** | Classify into z-layers, compute global padding, find intersections. |
|
|
108
|
+
| 2 | **Registration** | ZNCC pixel search + IC-GN Lucas–Kanade refinement per pair. |
|
|
109
|
+
| 3 | **Accumulate displacements** | Chain per-pair shifts into a global warp graph (BFS). |
|
|
110
|
+
| 4 | **Equalisation** | Match intensities across overlaps via joint histograms. |
|
|
111
|
+
| 5 | **Blending** | Distance-map blending onto the global canvas, on the GPU. |
|
|
112
|
+
| 6 | **Save and inspect** | Write per-layer `.h5` files with full pipeline metadata. |
|
|
113
|
+
|
|
114
|
+
The full per-stage walk-through with the code for every step lives in the
|
|
115
|
+
**detailed notebook** linked above. The math behind the registration and
|
|
116
|
+
blending lives in [PUBLICATION].
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Where you can use it
|
|
121
|
+
|
|
122
|
+
- Stitching **3D X-ray tomography reconstructions** from a multi-tile
|
|
123
|
+
translation scan.
|
|
124
|
+
- Stitching **raw projection volumes** (radiographs) before reconstruction.
|
|
125
|
+
- Stitching **3D microscopy datasets** (light-sheet, confocal) where individual
|
|
126
|
+
tiles are too large to fit into memory.
|
|
127
|
+
- **Multi-scan** stitching where you have several scans with overlapping
|
|
128
|
+
lateral extent.
|
|
129
|
+
- Stitching on a **rotation stage** (helical or tomographic) — see
|
|
130
|
+
`notebooks/03_stitching_with_rotation.ipynb`.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Install
|
|
135
|
+
|
|
136
|
+
TomoImageStitcher is on PyPI. A CUDA-capable GPU with the matching CuPy wheel
|
|
137
|
+
is required for the GPU stages; everything else is plain Python.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 1. (Recommended) a clean environment
|
|
141
|
+
python -m venv .venv && source .venv/bin/activate
|
|
142
|
+
|
|
143
|
+
# 2. Install with the notebook extras
|
|
144
|
+
pip install -U pip
|
|
145
|
+
pip install "tomo-image-stitcher[notebook,danmax]"
|
|
146
|
+
|
|
147
|
+
# 3. Install CuPy matching your CUDA version (CUDA 12.x shown)
|
|
148
|
+
pip install cupy-cuda12x
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
If you cannot install `git`, or you are behind a proxy that blocks it:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip install https://github.com/indrajeettambe/TomoImageStitcher/archive/main.zip
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
For full instructions (drivers, conda env, troubleshooting) see
|
|
158
|
+
[`docs/installation.md`](docs/installation.md).
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Quick start
|
|
163
|
+
|
|
164
|
+
A minimal end-to-end example on synthetic data. The full version with
|
|
165
|
+
explanations and intermediate visualisations is in
|
|
166
|
+
[`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb).
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
import numpy as np
|
|
170
|
+
from tomo_image_stitcher import Stitcher
|
|
171
|
+
|
|
172
|
+
# 1. List of .h5 files and their motor positions in millimetres
|
|
173
|
+
file_paths = ["scan_001.h5", "scan_002.h5", "scan_003.h5"]
|
|
174
|
+
motor_coords = np.array([[ 0.0, 0.0, 0.0],
|
|
175
|
+
[ 0.8, 0.0, 0.0],
|
|
176
|
+
[ 1.6, 0.0, 0.0]])
|
|
177
|
+
mm_per_voxel = 0.0022 # 2.2 µm voxels
|
|
178
|
+
|
|
179
|
+
# 2. Initialise the stitcher
|
|
180
|
+
st = Stitcher(file_paths, motor_coords, mm_per_voxel,
|
|
181
|
+
x_y_z_correspondance=(-1, 3, 2))
|
|
182
|
+
|
|
183
|
+
# 3. Run the six stages
|
|
184
|
+
st.get_layers_in_z(tolerance_mm=4) # (1) Organise
|
|
185
|
+
st.get_padding()
|
|
186
|
+
st.get_intersections(check=True)
|
|
187
|
+
st.compute_shift_in_layers(downscale=4, downscale_stages=4, # (2) Registration
|
|
188
|
+
downscale_LC=True, mask=True, mask_radius=300)
|
|
189
|
+
st.get_displacement_pyramid(check=False)
|
|
190
|
+
st.accumulate_displacement(exclude_NCC=50) # (3) Accumulate
|
|
191
|
+
st.compose_final_displacements()
|
|
192
|
+
st.stitch_volumes_blend_equalize(...) # (4) + (5) Equalise + Blend
|
|
193
|
+
st.stitch_layers(path_save="output/") # (6) Save
|
|
194
|
+
|
|
195
|
+
# 4. Read the stitched volume
|
|
196
|
+
import h5py
|
|
197
|
+
with h5py.File("output/Stitched_layers/Layer_0.h5", "r") as f:
|
|
198
|
+
volume = f["stitched_data/stitched_image"][:]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Documentation
|
|
204
|
+
|
|
205
|
+
| Resource | Description |
|
|
206
|
+
|----------|-------------|
|
|
207
|
+
| [`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb) | **Detailed step-by-step walkthrough** of the full pipeline on synthetic data. Start here. |
|
|
208
|
+
| [`notebooks/01_quickstart.ipynb`](notebooks/01_quickstart.ipynb) | Minimal 5-line end-to-end example. |
|
|
209
|
+
| [`notebooks/03_stitching_with_rotation.ipynb`](notebooks/03_stitching_with_rotation.ipynb) | Original DanMAX rotation-stage example (update paths before running). |
|
|
210
|
+
| [`docs/architecture.md`](docs/architecture.md) | Data structures used between pipeline stages. |
|
|
211
|
+
| [`docs/api.md`](docs/api.md) | Public classes, methods, and parameters. |
|
|
212
|
+
| [`docs/quickstart.md`](docs/quickstart.md) | More copy-paste recipes. |
|
|
213
|
+
| [`docs/troubleshooting.md`](docs/troubleshooting.md) | Common errors and how to recover. |
|
|
214
|
+
|
|
215
|
+
The mathematical details of the registration (ZNCC, IC-GN Lucas–Kanade, mask
|
|
216
|
+
weighting) and blending (distance-map weighting) are described in
|
|
217
|
+
**[PUBLICATION]**.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Project layout
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
TomoImageStitcher/
|
|
225
|
+
├── src/tomo_image_stitcher/ Package source (Stitcher, RegistrationKIT, …)
|
|
226
|
+
├── notebooks/ Jupyter tutorials (start with 02_full_pipeline)
|
|
227
|
+
├── examples/ Standalone Python scripts
|
|
228
|
+
├── tests/ pytest test-suite
|
|
229
|
+
├── docs/ Architecture, API, troubleshooting
|
|
230
|
+
├── pyproject.toml Build & dependency metadata
|
|
231
|
+
├── LICENSE MIT
|
|
232
|
+
└── CITATION.cff Software citation
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Citation
|
|
238
|
+
|
|
239
|
+
If you use TomoImageStitcher in your research, please cite it using the
|
|
240
|
+
metadata in [`CITATION.cff`](CITATION.cff). A publication describing the
|
|
241
|
+
algorithm is in preparation and will be linked here when available
|
|
242
|
+
([PUBLICATION]).
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
249
|
+
|
|
250
|
+
## Contributors
|
|
251
|
+
|
|
252
|
+
TomoImageStitcher was originally developed at the **DanMAX** beamline
|
|
253
|
+
(MAX IV Laboratory, Sweden). See the git log for the full list of
|
|
254
|
+
contributors.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# TomoImageStitcher
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/psf/black)
|
|
6
|
+
[](https://cupy.dev/)
|
|
7
|
+
|
|
8
|
+
A GPU-accelerated, sub-pixel accurate **3D volumetric stitcher** for tomographic and
|
|
9
|
+
large-volume microscopy datasets. TomoImageStitcher registers overlapping 3D
|
|
10
|
+
sub-volumes acquired on a translation (and optionally rotation) stage and produces
|
|
11
|
+
a single seamless volume with mask-aware blending and optional intensity
|
|
12
|
+
equalisation.
|
|
13
|
+
|
|
14
|
+
> Originally developed for stitching local X-ray tomography volumes for the Experiment at the **DanMAX** beamline, Sweden.
|
|
15
|
+
|
|
16
|
+
For a **detailed step-by-step walkthrough** of every pipeline stage with synthetic
|
|
17
|
+
data, see [`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb).
|
|
18
|
+
For the mathematical details of the registration, see **[PUBLICATION]**.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## What is it
|
|
23
|
+
|
|
24
|
+
TomoImageStitcher stitches together a set of **overlapping 3D sub-volumes**
|
|
25
|
+
(typically reconstructed tomography volumes) into **one seamless volume**.
|
|
26
|
+
Each stage is a Python call on the `Stitcher` object, so you can inspect and
|
|
27
|
+
re-run any stage on its own.
|
|
28
|
+
|
|
29
|
+
The pipeline runs in **six stages**:
|
|
30
|
+
|
|
31
|
+
| # | Stage | What it does |
|
|
32
|
+
|---|-------|--------------|
|
|
33
|
+
| 1 | **Organise sub-volumes** | Classify into z-layers, compute global padding, find intersections. |
|
|
34
|
+
| 2 | **Registration** | ZNCC pixel search + IC-GN Lucas–Kanade refinement per pair. |
|
|
35
|
+
| 3 | **Accumulate displacements** | Chain per-pair shifts into a global warp graph (BFS). |
|
|
36
|
+
| 4 | **Equalisation** | Match intensities across overlaps via joint histograms. |
|
|
37
|
+
| 5 | **Blending** | Distance-map blending onto the global canvas, on the GPU. |
|
|
38
|
+
| 6 | **Save and inspect** | Write per-layer `.h5` files with full pipeline metadata. |
|
|
39
|
+
|
|
40
|
+
The full per-stage walk-through with the code for every step lives in the
|
|
41
|
+
**detailed notebook** linked above. The math behind the registration and
|
|
42
|
+
blending lives in [PUBLICATION].
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Where you can use it
|
|
47
|
+
|
|
48
|
+
- Stitching **3D X-ray tomography reconstructions** from a multi-tile
|
|
49
|
+
translation scan.
|
|
50
|
+
- Stitching **raw projection volumes** (radiographs) before reconstruction.
|
|
51
|
+
- Stitching **3D microscopy datasets** (light-sheet, confocal) where individual
|
|
52
|
+
tiles are too large to fit into memory.
|
|
53
|
+
- **Multi-scan** stitching where you have several scans with overlapping
|
|
54
|
+
lateral extent.
|
|
55
|
+
- Stitching on a **rotation stage** (helical or tomographic) — see
|
|
56
|
+
`notebooks/03_stitching_with_rotation.ipynb`.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Install
|
|
61
|
+
|
|
62
|
+
TomoImageStitcher is on PyPI. A CUDA-capable GPU with the matching CuPy wheel
|
|
63
|
+
is required for the GPU stages; everything else is plain Python.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# 1. (Recommended) a clean environment
|
|
67
|
+
python -m venv .venv && source .venv/bin/activate
|
|
68
|
+
|
|
69
|
+
# 2. Install with the notebook extras
|
|
70
|
+
pip install -U pip
|
|
71
|
+
pip install "tomo-image-stitcher[notebook,danmax]"
|
|
72
|
+
|
|
73
|
+
# 3. Install CuPy matching your CUDA version (CUDA 12.x shown)
|
|
74
|
+
pip install cupy-cuda12x
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If you cannot install `git`, or you are behind a proxy that blocks it:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install https://github.com/indrajeettambe/TomoImageStitcher/archive/main.zip
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For full instructions (drivers, conda env, troubleshooting) see
|
|
84
|
+
[`docs/installation.md`](docs/installation.md).
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Quick start
|
|
89
|
+
|
|
90
|
+
A minimal end-to-end example on synthetic data. The full version with
|
|
91
|
+
explanations and intermediate visualisations is in
|
|
92
|
+
[`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb).
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import numpy as np
|
|
96
|
+
from tomo_image_stitcher import Stitcher
|
|
97
|
+
|
|
98
|
+
# 1. List of .h5 files and their motor positions in millimetres
|
|
99
|
+
file_paths = ["scan_001.h5", "scan_002.h5", "scan_003.h5"]
|
|
100
|
+
motor_coords = np.array([[ 0.0, 0.0, 0.0],
|
|
101
|
+
[ 0.8, 0.0, 0.0],
|
|
102
|
+
[ 1.6, 0.0, 0.0]])
|
|
103
|
+
mm_per_voxel = 0.0022 # 2.2 µm voxels
|
|
104
|
+
|
|
105
|
+
# 2. Initialise the stitcher
|
|
106
|
+
st = Stitcher(file_paths, motor_coords, mm_per_voxel,
|
|
107
|
+
x_y_z_correspondance=(-1, 3, 2))
|
|
108
|
+
|
|
109
|
+
# 3. Run the six stages
|
|
110
|
+
st.get_layers_in_z(tolerance_mm=4) # (1) Organise
|
|
111
|
+
st.get_padding()
|
|
112
|
+
st.get_intersections(check=True)
|
|
113
|
+
st.compute_shift_in_layers(downscale=4, downscale_stages=4, # (2) Registration
|
|
114
|
+
downscale_LC=True, mask=True, mask_radius=300)
|
|
115
|
+
st.get_displacement_pyramid(check=False)
|
|
116
|
+
st.accumulate_displacement(exclude_NCC=50) # (3) Accumulate
|
|
117
|
+
st.compose_final_displacements()
|
|
118
|
+
st.stitch_volumes_blend_equalize(...) # (4) + (5) Equalise + Blend
|
|
119
|
+
st.stitch_layers(path_save="output/") # (6) Save
|
|
120
|
+
|
|
121
|
+
# 4. Read the stitched volume
|
|
122
|
+
import h5py
|
|
123
|
+
with h5py.File("output/Stitched_layers/Layer_0.h5", "r") as f:
|
|
124
|
+
volume = f["stitched_data/stitched_image"][:]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Documentation
|
|
130
|
+
|
|
131
|
+
| Resource | Description |
|
|
132
|
+
|----------|-------------|
|
|
133
|
+
| [`notebooks/02_full_pipeline.ipynb`](notebooks/02_full_pipeline.ipynb) | **Detailed step-by-step walkthrough** of the full pipeline on synthetic data. Start here. |
|
|
134
|
+
| [`notebooks/01_quickstart.ipynb`](notebooks/01_quickstart.ipynb) | Minimal 5-line end-to-end example. |
|
|
135
|
+
| [`notebooks/03_stitching_with_rotation.ipynb`](notebooks/03_stitching_with_rotation.ipynb) | Original DanMAX rotation-stage example (update paths before running). |
|
|
136
|
+
| [`docs/architecture.md`](docs/architecture.md) | Data structures used between pipeline stages. |
|
|
137
|
+
| [`docs/api.md`](docs/api.md) | Public classes, methods, and parameters. |
|
|
138
|
+
| [`docs/quickstart.md`](docs/quickstart.md) | More copy-paste recipes. |
|
|
139
|
+
| [`docs/troubleshooting.md`](docs/troubleshooting.md) | Common errors and how to recover. |
|
|
140
|
+
|
|
141
|
+
The mathematical details of the registration (ZNCC, IC-GN Lucas–Kanade, mask
|
|
142
|
+
weighting) and blending (distance-map weighting) are described in
|
|
143
|
+
**[PUBLICATION]**.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Project layout
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
TomoImageStitcher/
|
|
151
|
+
├── src/tomo_image_stitcher/ Package source (Stitcher, RegistrationKIT, …)
|
|
152
|
+
├── notebooks/ Jupyter tutorials (start with 02_full_pipeline)
|
|
153
|
+
├── examples/ Standalone Python scripts
|
|
154
|
+
├── tests/ pytest test-suite
|
|
155
|
+
├── docs/ Architecture, API, troubleshooting
|
|
156
|
+
├── pyproject.toml Build & dependency metadata
|
|
157
|
+
├── LICENSE MIT
|
|
158
|
+
└── CITATION.cff Software citation
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Citation
|
|
164
|
+
|
|
165
|
+
If you use TomoImageStitcher in your research, please cite it using the
|
|
166
|
+
metadata in [`CITATION.cff`](CITATION.cff). A publication describing the
|
|
167
|
+
algorithm is in preparation and will be linked here when available
|
|
168
|
+
([PUBLICATION]).
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
175
|
+
|
|
176
|
+
## Contributors
|
|
177
|
+
|
|
178
|
+
TomoImageStitcher was originally developed at the **DanMAX** beamline
|
|
179
|
+
(MAX IV Laboratory, Sweden). See the git log for the full list of
|
|
180
|
+
contributors.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Install with: pip install -e .
|
|
2
|
+
|
|
3
|
+
[build-system]
|
|
4
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
5
|
+
build-backend = "setuptools.build_meta"
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "tomo-image-stitcher"
|
|
9
|
+
version = "0.2.0"
|
|
10
|
+
description = "GPU-accelerated 3D volumetric stitcher for tomographic and microscopy volumes."
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
license = {file = "LICENSE"}
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Endri Lacaj"},
|
|
15
|
+
{name = "Indrajeet Tambe"},
|
|
16
|
+
]
|
|
17
|
+
keywords = ["stitching", "tomography", "registration", "GPU", "CuPy", "volume-stitching", "3D"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 4 - Beta",
|
|
20
|
+
"Intended Audience :: Science/Research",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Operating System :: POSIX :: Linux",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.9",
|
|
25
|
+
"Programming Language :: Python :: 3.10",
|
|
26
|
+
"Programming Language :: Python :: 3.11",
|
|
27
|
+
"Programming Language :: Python :: 3.12",
|
|
28
|
+
"Topic :: Scientific/Engineering",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
30
|
+
]
|
|
31
|
+
requires-python = ">=3.9"
|
|
32
|
+
dependencies = [
|
|
33
|
+
"numpy>=1.23",
|
|
34
|
+
"scipy>=1.10",
|
|
35
|
+
"scikit-learn>=1.2",
|
|
36
|
+
"h5py>=3.8",
|
|
37
|
+
"tifffile>=2023.4",
|
|
38
|
+
"imagecodecs>=2023.1",
|
|
39
|
+
"SimpleITK>=2.3",
|
|
40
|
+
"scikit-image>=0.20",
|
|
41
|
+
"matplotlib>=3.7",
|
|
42
|
+
"tqdm>=4.65",
|
|
43
|
+
"cupy-cuda12x>=13.0; sys_platform != 'darwin'",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.optional-dependencies]
|
|
47
|
+
danmax = [
|
|
48
|
+
"ipywidgets>=8.0",
|
|
49
|
+
"pyFAI>=2023.1",
|
|
50
|
+
"pytz>=2023.3",
|
|
51
|
+
]
|
|
52
|
+
notebook = [
|
|
53
|
+
"jupyter>=1.0",
|
|
54
|
+
"ipykernel>=6.0",
|
|
55
|
+
"notebook>=7.0",
|
|
56
|
+
]
|
|
57
|
+
dev = [
|
|
58
|
+
"pytest>=7.3",
|
|
59
|
+
"pytest-cov>=4.0",
|
|
60
|
+
"black>=23.0",
|
|
61
|
+
"flake8>=6.0",
|
|
62
|
+
"isort>=5.12",
|
|
63
|
+
]
|
|
64
|
+
all = ["tomo-image-stitcher[danmax,notebook,dev]"]
|
|
65
|
+
|
|
66
|
+
[project.urls]
|
|
67
|
+
Homepage = "https://github.com/indrajeettambe/TomoImageStitcher"
|
|
68
|
+
Issues = "https://github.com/indrajeettambe/TomoImageStitcher/issues"
|
|
69
|
+
Documentation = "https://github.com/indrajeettambe/TomoImageStitcher/tree/main/docs"
|
|
70
|
+
|
|
71
|
+
[tool.setuptools.packages.find]
|
|
72
|
+
where = ["src"]
|
|
73
|
+
include = ["tomo_image_stitcher*"]
|
|
74
|
+
|
|
75
|
+
[tool.setuptools.package-data]
|
|
76
|
+
tomo_image_stitcher = ["py.typed"]
|
|
77
|
+
|
|
78
|
+
[tool.black]
|
|
79
|
+
line-length = 100
|
|
80
|
+
target-version = ["py39", "py310", "py311", "py312"]
|
|
81
|
+
|
|
82
|
+
[tool.isort]
|
|
83
|
+
profile = "black"
|
|
84
|
+
line_length = 100
|
|
85
|
+
|
|
86
|
+
[tool.pytest.ini_options]
|
|
87
|
+
testpaths = ["tests"]
|
|
88
|
+
python_files = "test_*.py"
|
|
89
|
+
addopts = "-ra --strict-markers"
|
|
90
|
+
filterwarnings = [
|
|
91
|
+
"ignore::RuntimeWarning",
|
|
92
|
+
]
|
|
93
|
+
markers = [
|
|
94
|
+
"slow: marks tests as slow (deselect with -m 'not slow')",
|
|
95
|
+
"gpu: marks tests that require a CUDA-capable GPU",
|
|
96
|
+
]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TomoImageStitcher — GPU-accelerated 3D volumetric stitching.
|
|
3
|
+
|
|
4
|
+
A package for stitching 3D sub-volumes (tomography reconstructions,
|
|
5
|
+
projection volumes, etc.) using a ZNCC pixel search followed by an
|
|
6
|
+
inverse-compositional Lucas-Kanade refinement, with mask-aware
|
|
7
|
+
blending on the GPU.
|
|
8
|
+
|
|
9
|
+
Modules
|
|
10
|
+
-------
|
|
11
|
+
stitcher Main ``Stitcher`` class driving the full pipeline.
|
|
12
|
+
registration ``RegistrationKIT`` with ZNCC and IC-GN Lucas-Kanade engines.
|
|
13
|
+
transform ``affine_transform_large_data`` for chunked GPU affine warps.
|
|
14
|
+
utilities H5 I/O helpers, circular masks, distance functions.
|
|
15
|
+
danmax Optional DanMAX beamline utilities.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from .stitcher import Stitcher, Utilities
|
|
19
|
+
from .registration import RegistrationKIT
|
|
20
|
+
from .transform import affine_transform_large_data
|
|
21
|
+
|
|
22
|
+
__version__ = "0.2.0"
|
|
23
|
+
__author__ = "Endri Lacaj, Indrajeet Tambe"
|
|
24
|
+
__license__ = "MIT"
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"Stitcher",
|
|
28
|
+
"Utilities",
|
|
29
|
+
"RegistrationKIT",
|
|
30
|
+
"affine_transform_large_data",
|
|
31
|
+
"__version__",
|
|
32
|
+
]
|