dbdicom 0.2.1__py3-none-any.whl → 0.2.3__py3-none-any.whl
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.
Potentially problematic release.
This version of dbdicom might be problematic. Click here for more details.
- dbdicom/__init__.py +4 -3
- dbdicom/create.py +34 -97
- dbdicom/dro.py +174 -0
- dbdicom/ds/dataset.py +29 -3
- dbdicom/ds/types/mr_image.py +18 -7
- dbdicom/extensions/__init__.py +10 -0
- dbdicom/{wrappers → extensions}/dipy.py +191 -205
- dbdicom/extensions/elastix.py +503 -0
- dbdicom/extensions/matplotlib.py +107 -0
- dbdicom/extensions/numpy.py +271 -0
- dbdicom/{wrappers → extensions}/scipy.py +130 -31
- dbdicom/{wrappers → extensions}/skimage.py +1 -1
- dbdicom/extensions/sklearn.py +243 -0
- dbdicom/extensions/vreg.py +1390 -0
- dbdicom/external/dcm4che/bin/emf2sf +57 -57
- dbdicom/manager.py +70 -36
- dbdicom/pipelines.py +66 -0
- dbdicom/record.py +266 -43
- dbdicom/types/instance.py +17 -3
- dbdicom/types/series.py +1900 -404
- dbdicom/utils/image.py +152 -21
- dbdicom/utils/vreg.py +327 -135
- dbdicom-0.2.3.dist-info/METADATA +88 -0
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/RECORD +27 -41
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/WHEEL +1 -1
- dbdicom/external/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-310.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-37.pyc +0 -0
- dbdicom/external/dcm4che/lib/linux-x86/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/linux-x86-64/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/linux-x86-64/libopencv_java.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis2.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis2.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-x86/libclib_jiio.so +0 -0
- dbdicom/external/dcm4che/lib/solaris-x86-64/libclib_jiio.so +0 -0
- dbdicom/wrappers/__init__.py +0 -7
- dbdicom/wrappers/elastix.py +0 -855
- dbdicom/wrappers/numpy.py +0 -119
- dbdicom/wrappers/sklearn.py +0 -151
- dbdicom/wrappers/vreg.py +0 -273
- dbdicom-0.2.1.dist-info/METADATA +0 -276
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/LICENSE +0 -0
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.3.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
|
|
3
3
|
from dipy.align.metrics import CCMetric, EMMetric, SSDMetric
|
|
4
|
-
from dipy.align.imaffine import MutualInformationMetric, AffineRegistration
|
|
5
|
-
from dipy.align.transforms import (
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
from dipy.align.imaffine import MutualInformationMetric, AffineRegistration, transform_centers_of_mass
|
|
5
|
+
from dipy.align.transforms import (
|
|
6
|
+
TranslationTransform2D, RigidTransform2D, AffineTransform2D,
|
|
7
|
+
TranslationTransform3D, RigidTransform3D, AffineTransform3D)
|
|
8
8
|
from dipy.align import center_of_mass
|
|
9
9
|
from dipy.align.vector_fields import (
|
|
10
10
|
warp_3d_nn,
|
|
@@ -16,11 +16,7 @@ from dipy.align.vector_fields import (
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
from dipy.segment.mask import median_otsu as median_otsu_np
|
|
19
|
-
import dbdicom.
|
|
20
|
-
from dbdicom.utils.image import slice_to_volume
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
import dbdicom.extensions.vreg as vreg
|
|
24
20
|
|
|
25
21
|
|
|
26
22
|
def median_otsu(series, **kwargs):
|
|
@@ -52,7 +48,7 @@ def align_center_of_mass_3d(moving, fixed):
|
|
|
52
48
|
|
|
53
49
|
# Get arrays for fixed and moving series
|
|
54
50
|
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
55
|
-
array_fixed =
|
|
51
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
56
52
|
|
|
57
53
|
# Coregister fixed and moving slice-by-slice
|
|
58
54
|
identity = np.eye(4)
|
|
@@ -69,164 +65,238 @@ def coregister_translation_3d(moving, fixed):
|
|
|
69
65
|
|
|
70
66
|
# Get arrays for fixed and moving series
|
|
71
67
|
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
72
|
-
array_fixed =
|
|
68
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
69
|
+
|
|
70
|
+
# Set up coregistration
|
|
71
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None,)
|
|
72
|
+
affreg = AffineRegistration(
|
|
73
|
+
metric = metric,
|
|
74
|
+
level_iters = [10000, 1000, 100],
|
|
75
|
+
sigmas = [3.0, 1.0, 0.0],
|
|
76
|
+
factors = [4, 2, 1],
|
|
77
|
+
)
|
|
78
|
+
transform = TranslationTransform3D()
|
|
79
|
+
params0 = None
|
|
73
80
|
|
|
74
|
-
#
|
|
81
|
+
# Perform coregistration
|
|
75
82
|
moving.message('Performing coregistration..')
|
|
76
|
-
|
|
83
|
+
mapping = affreg.optimize(array_fixed, array_moving, transform, params0)
|
|
84
|
+
coregistered = mapping.transform(array_moving, 'linear')
|
|
77
85
|
|
|
78
|
-
#
|
|
86
|
+
# Save as DICOM
|
|
79
87
|
coreg = moving.new_sibling(suffix='translated')
|
|
80
88
|
coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
81
89
|
|
|
82
90
|
return coreg
|
|
83
91
|
|
|
84
92
|
|
|
85
|
-
def coregister_rigid_3d(moving,
|
|
93
|
+
def coregister_rigid_3d(moving, fixed):
|
|
86
94
|
|
|
87
95
|
# Get arrays for fixed and moving series
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
array_static, headers_static = static.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
92
|
-
array_moving = scipy.array(moving, on=static, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
96
|
+
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
97
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
93
98
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
# Setup coregistration
|
|
100
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None)
|
|
101
|
+
affreg = AffineRegistration(
|
|
102
|
+
metric = metric,
|
|
103
|
+
level_iters = [10000, 1000, 100],
|
|
104
|
+
sigmas = [3.0, 1.0, 0.0],
|
|
105
|
+
factors = [4, 2, 1],
|
|
106
|
+
)
|
|
107
|
+
transform = RigidTransform3D()
|
|
108
|
+
params0 = None
|
|
101
109
|
|
|
102
|
-
#
|
|
110
|
+
# Perform coregistration
|
|
103
111
|
moving.message('Performing coregistration..')
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
mapping = affreg.optimize(array_fixed, array_moving, transform, params0)
|
|
113
|
+
coregistered = mapping.transform(array_moving, 'linear')
|
|
114
|
+
|
|
115
|
+
# Save as DICOM
|
|
116
|
+
coreg = moving.new_sibling(suffix='rigid transform')
|
|
117
|
+
coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
118
|
+
return coreg
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def coregister_affine_3d(moving, fixed):
|
|
123
|
+
|
|
124
|
+
# Get arrays for fixed and moving series
|
|
125
|
+
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
126
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
127
|
+
|
|
128
|
+
# Setup coregistration
|
|
129
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None)
|
|
130
|
+
affreg = AffineRegistration(
|
|
131
|
+
metric = metric,
|
|
132
|
+
level_iters = [10000, 1000, 100],
|
|
133
|
+
sigmas = [3.0, 1.0, 0.0],
|
|
134
|
+
factors = [4, 2, 1],
|
|
109
135
|
)
|
|
136
|
+
transform = AffineTransform3D()
|
|
137
|
+
params0 = None
|
|
110
138
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
139
|
+
# Perform coregistration
|
|
140
|
+
moving.message('Performing coregistration..')
|
|
141
|
+
mapping = affreg.optimize(array_fixed, array_moving, transform, params0)
|
|
142
|
+
coregistered = mapping.transform(array_moving, 'linear')
|
|
143
|
+
|
|
144
|
+
# Save as DICOM
|
|
145
|
+
coreg = moving.new_sibling(suffix='rigid transform')
|
|
146
|
+
coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
116
147
|
return coreg
|
|
117
148
|
|
|
118
149
|
|
|
119
|
-
|
|
120
|
-
def WIP_coregister_rigid_3d(moving, static, ignore_empty_slices=False):
|
|
150
|
+
def coregister_deformable_3d(moving, fixed, **kwargs):
|
|
121
151
|
|
|
122
|
-
# Get affines for fixed and moving series
|
|
123
|
-
affine_moving = moving.affine_matrix()
|
|
124
|
-
affine_static = static.affine_matrix()
|
|
125
|
-
|
|
126
|
-
# If there are multiple slice groups - raise error
|
|
127
|
-
if isinstance(affine_moving, list):
|
|
128
|
-
msg = 'Moving series consists of multiple slice groups.\n'
|
|
129
|
-
msg += 'Can only align series consisting of a single slice group.'
|
|
130
|
-
raise ValueError(msg)
|
|
131
|
-
if isinstance(affine_static, list):
|
|
132
|
-
msg = 'Static series consists of multiple slice groups.\n'
|
|
133
|
-
msg += 'Can only align series consisting of a single slice group.'
|
|
134
|
-
raise ValueError(msg)
|
|
135
|
-
|
|
136
|
-
# Get affine matrices
|
|
137
|
-
affine_static = affine_static[0].astype(np.double)
|
|
138
|
-
affine_moving = affine_moving[0].astype(np.double)
|
|
139
|
-
|
|
140
152
|
# Get arrays for fixed and moving series
|
|
141
|
-
# array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
142
|
-
# array_static, _ = static.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
143
|
-
array_static, headers_static = static.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
144
153
|
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
154
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
145
155
|
|
|
146
|
-
#
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if array_static.shape[2] == 1:
|
|
150
|
-
array_static, affine_static = slice_to_volume(array_static, affine_static)
|
|
156
|
+
# Perform coregistration
|
|
157
|
+
moving.status.message('Performing coregistration..')
|
|
158
|
+
array_moving, deformation = _coregister_arrays(array_fixed, array_moving, **kwargs)
|
|
151
159
|
|
|
152
|
-
#
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
static_mask = _coregistration_mask_3d(array_static)
|
|
156
|
-
else:
|
|
157
|
-
moving_mask = None
|
|
158
|
-
static_mask = None
|
|
160
|
+
# Create new series
|
|
161
|
+
coreg = moving.new_sibling(suffix='registered')
|
|
162
|
+
deform = moving.new_sibling(suffix='deformation field')
|
|
159
163
|
|
|
160
|
-
#
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
static_mask = static_mask,
|
|
168
|
-
moving_mask = moving_mask,
|
|
169
|
-
)
|
|
164
|
+
# Set arrays
|
|
165
|
+
coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
166
|
+
for dim in range(deformation.shape[-1]):
|
|
167
|
+
deform.set_array(deformation[...,dim], headers_moving, pixels_first=True)
|
|
168
|
+
|
|
169
|
+
# Return coregistered images and deformation field
|
|
170
|
+
return coreg, deform
|
|
170
171
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
|
|
173
|
+
def align_center_of_mass_2d(moving, fixed):
|
|
174
|
+
|
|
175
|
+
# Get arrays for fixed and moving series
|
|
176
|
+
zaxis = 'SliceLocation'
|
|
177
|
+
array_moving = moving.pixel_values(zaxis)
|
|
178
|
+
array_fixed = vreg.pixel_values(fixed, zaxis, on=moving)
|
|
179
|
+
|
|
180
|
+
# Coregister fixed and moving slice-by-slice
|
|
181
|
+
id = np.eye(3)
|
|
182
|
+
for z in range(array_moving.shape[2]):
|
|
183
|
+
moving.progress(z+1, array_moving.shape[2], 'Performing coregistration..')
|
|
184
|
+
c_of_mass = transform_centers_of_mass(array_fixed[:,:,z], id, array_moving[:,:,z], id)
|
|
185
|
+
array_moving[:,:,z] = c_of_mass.transform(array_moving[:,:,z])
|
|
186
|
+
|
|
187
|
+
# Save as DICOM (new API)
|
|
188
|
+
coreg = moving.copy(SeriesDescription=moving.SeriesDescription + ' [coreg]')
|
|
189
|
+
coreg.set_pixel_values(array_moving, coords=moving.coords(zaxis))
|
|
176
190
|
return coreg
|
|
177
191
|
|
|
178
192
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
|
|
194
|
+
def coregister_translation_2d(moving, fixed):
|
|
195
|
+
|
|
196
|
+
# # Get arrays for fixed and moving series (old API)
|
|
197
|
+
# array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
198
|
+
# array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
199
|
+
|
|
200
|
+
# Get arrays for fixed and moving series (new API)
|
|
201
|
+
#zaxis = ('SliceLocation',)
|
|
202
|
+
zaxis = 'SliceLocation'
|
|
203
|
+
array_moving = moving.pixel_values(zaxis)
|
|
204
|
+
array_fixed = vreg.pixel_values(fixed, zaxis, on=moving)
|
|
205
|
+
|
|
206
|
+
# Set up coregistration
|
|
207
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None)
|
|
208
|
+
affreg = AffineRegistration(
|
|
209
|
+
metric = metric,
|
|
210
|
+
level_iters = [10000, 1000, 100],
|
|
211
|
+
sigmas = [3.0, 1.0, 0.0],
|
|
212
|
+
factors = [4, 2, 1],
|
|
184
213
|
)
|
|
214
|
+
transform = TranslationTransform2D()
|
|
215
|
+
|
|
216
|
+
# Coregister fixed and moving slice-by-slice
|
|
217
|
+
for z in range(array_moving.shape[2]):
|
|
218
|
+
moving.progress(z+1, array_moving.shape[2], 'Performing coregistration..')
|
|
219
|
+
# Coregister slice
|
|
220
|
+
params0 = None
|
|
221
|
+
mapping = affreg.optimize(array_fixed[:,:,z], array_moving[:,:,z], transform, params0)
|
|
222
|
+
array_moving[:,:,z] = mapping.transform(array_moving[:,:,z], 'linear')
|
|
223
|
+
|
|
224
|
+
# # Save as DICOM (old API)
|
|
225
|
+
# coreg = moving.new_sibling(suffix= 'registered')
|
|
226
|
+
# coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
227
|
+
|
|
228
|
+
# Save as DICOM (new API)
|
|
229
|
+
coreg = moving.copy(SeriesDescription=moving.SeriesDescription + ' [coreg]')
|
|
230
|
+
coreg.set_pixel_values(array_moving, coords=moving.coords(zaxis))
|
|
231
|
+
return coreg
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def coregister_rigid_2d(moving, fixed):
|
|
235
|
+
|
|
236
|
+
# Get arrays for fixed and moving series
|
|
237
|
+
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
238
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
239
|
+
|
|
240
|
+
# Set up coregistration
|
|
241
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None)
|
|
185
242
|
affreg = AffineRegistration(
|
|
186
243
|
metric = metric,
|
|
187
244
|
level_iters = [10000, 1000, 100],
|
|
188
245
|
sigmas = [3.0, 1.0, 0.0],
|
|
189
246
|
factors = [4, 2, 1],
|
|
190
247
|
)
|
|
191
|
-
transform =
|
|
192
|
-
params0 = None
|
|
193
|
-
mapping = affreg.optimize(static, moving, transform, params0, **kwargs)
|
|
248
|
+
transform = RigidTransform2D()
|
|
194
249
|
|
|
195
|
-
#
|
|
196
|
-
|
|
250
|
+
# Coregister fixed and moving slice-by-slice
|
|
251
|
+
for z in range(array_moving.shape[2]):
|
|
252
|
+
moving.status.progress(z+1, array_moving.shape[2], 'Performing coregistration..')
|
|
253
|
+
# Coregister slice
|
|
254
|
+
params0 = None
|
|
255
|
+
mapping = affreg.optimize(array_fixed[:,:,z], array_moving[:,:,z], transform, params0)
|
|
256
|
+
array_moving[:,:,z] = mapping.transform(array_moving[:,:,z], 'linear')
|
|
197
257
|
|
|
198
|
-
|
|
258
|
+
# Save as DICOM
|
|
259
|
+
coreg = moving.new_sibling(suffix= 'registered')
|
|
260
|
+
coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
261
|
+
return coreg
|
|
199
262
|
|
|
200
263
|
|
|
201
|
-
def
|
|
264
|
+
def coregister_affine_2d(moving, fixed):
|
|
202
265
|
|
|
203
266
|
# Get arrays for fixed and moving series
|
|
204
267
|
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
205
|
-
array_fixed =
|
|
268
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
206
269
|
|
|
207
|
-
#
|
|
208
|
-
|
|
209
|
-
|
|
270
|
+
# Set up coregistration
|
|
271
|
+
metric = MutualInformationMetric(nbins=32, sampling_proportion=None)
|
|
272
|
+
affreg = AffineRegistration(
|
|
273
|
+
metric = metric,
|
|
274
|
+
level_iters = [10000, 1000, 100],
|
|
275
|
+
sigmas = [3.0, 1.0, 0.0],
|
|
276
|
+
factors = [4, 2, 1],
|
|
277
|
+
)
|
|
278
|
+
transform = AffineTransform2D()
|
|
210
279
|
|
|
211
|
-
#
|
|
212
|
-
|
|
213
|
-
|
|
280
|
+
# Coregister fixed and moving slice-by-slice
|
|
281
|
+
for z in range(array_moving.shape[2]):
|
|
282
|
+
moving.status.progress(z+1, array_moving.shape[2], 'Performing coregistration..')
|
|
283
|
+
# Coregister slice
|
|
284
|
+
params0 = None
|
|
285
|
+
mapping = affreg.optimize(array_fixed[:,:,z], array_moving[:,:,z], transform, params0)
|
|
286
|
+
array_moving[:,:,z] =mapping.transform(array_moving[:,:,z], 'linear')
|
|
214
287
|
|
|
288
|
+
# Save as DICOM
|
|
289
|
+
coreg = moving.new_sibling(suffix= 'registered')
|
|
290
|
+
coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
215
291
|
return coreg
|
|
216
292
|
|
|
217
293
|
|
|
218
|
-
def coregister_2d_to_2d(moving, fixed, **kwargs):
|
|
219
294
|
|
|
220
|
-
|
|
221
|
-
fixed_map = scipy.map_to(fixed, moving)
|
|
295
|
+
def coregister_deformable_2d(moving, fixed, **kwargs):
|
|
222
296
|
|
|
223
297
|
# Get arrays for fixed and moving series
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
# Remove overlay from database
|
|
228
|
-
if fixed_map != fixed:
|
|
229
|
-
fixed_map.remove()
|
|
298
|
+
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
299
|
+
array_fixed = vreg.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
230
300
|
|
|
231
301
|
# Coregister fixed and moving slice-by-slice
|
|
232
302
|
deformation = np.empty(array_moving.shape + (2,))
|
|
@@ -247,34 +317,7 @@ def coregister_2d_to_2d(moving, fixed, **kwargs):
|
|
|
247
317
|
return coreg, deform
|
|
248
318
|
|
|
249
319
|
|
|
250
|
-
def coregister_3d_to_3d(moving, fixed, **kwargs):
|
|
251
|
-
|
|
252
|
-
# Overlay fixed on moving image
|
|
253
|
-
fixed_map = scipy.map_to(fixed, moving)
|
|
254
|
-
|
|
255
|
-
# Get arrays for fixed and moving series
|
|
256
|
-
array_fixed, _ = fixed_map.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
257
|
-
array_moving, headers_moving = moving.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
258
|
-
|
|
259
|
-
# Remove overlay from database
|
|
260
|
-
if fixed_map != fixed:
|
|
261
|
-
fixed_map.remove()
|
|
262
320
|
|
|
263
|
-
# Perform coregistration
|
|
264
|
-
moving.status.message('Performing coregistration..')
|
|
265
|
-
array_moving, deformation = _coregister_arrays(array_fixed, array_moving, **kwargs)
|
|
266
|
-
|
|
267
|
-
# Create new series
|
|
268
|
-
coreg = moving.new_sibling(suffix='registered')
|
|
269
|
-
deform = moving.new_sibling(suffix='deformation field')
|
|
270
|
-
|
|
271
|
-
# Set arrays
|
|
272
|
-
coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
273
|
-
for dim in range(deformation.shape[-1]):
|
|
274
|
-
deform.set_array(deformation[...,dim], headers_moving, pixels_first=True)
|
|
275
|
-
|
|
276
|
-
# Return coregistered images and deformation field
|
|
277
|
-
return coreg, deform
|
|
278
321
|
|
|
279
322
|
|
|
280
323
|
|
|
@@ -295,16 +338,9 @@ def invert_deformation_field(deformation_field, **kwargs):
|
|
|
295
338
|
|
|
296
339
|
def warp(image, deformation_field, **kwargs):
|
|
297
340
|
|
|
298
|
-
# Overlay deformation field on image
|
|
299
|
-
deform = scipy.map_to(deformation_field, image)
|
|
300
|
-
|
|
301
341
|
# Get arrays
|
|
302
342
|
array, headers = image.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
303
|
-
array_deform
|
|
304
|
-
|
|
305
|
-
# Remove temporary variables
|
|
306
|
-
if deform != deformation_field:
|
|
307
|
-
deform.remove()
|
|
343
|
+
array_deform = vreg.array(deformation_field, on=image, sortby='SliceLocation', pixels_first=True)
|
|
308
344
|
|
|
309
345
|
# Perform warping
|
|
310
346
|
array = _warp_array(array, array_deform, image.status, **kwargs)
|
|
@@ -316,12 +352,10 @@ def warp(image, deformation_field, **kwargs):
|
|
|
316
352
|
return warped
|
|
317
353
|
|
|
318
354
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
mask[:,:,z] = 1
|
|
324
|
-
return mask
|
|
355
|
+
|
|
356
|
+
### ARRAY functions
|
|
357
|
+
|
|
358
|
+
|
|
325
359
|
|
|
326
360
|
|
|
327
361
|
def _invert_deformation_field_array(array, status, max_iter=10, tolerance=0.1):
|
|
@@ -366,59 +400,11 @@ def _warp_array(array, deform, status, interpolate=True):
|
|
|
366
400
|
raise ValueError(msg)
|
|
367
401
|
|
|
368
402
|
|
|
369
|
-
def _coregister_translation_3d_arrays(fixed, moving):
|
|
370
|
-
|
|
371
|
-
metric = MutualInformationMetric(
|
|
372
|
-
nbins=32,
|
|
373
|
-
sampling_proportion=None,
|
|
374
|
-
)
|
|
375
|
-
affreg = AffineRegistration(
|
|
376
|
-
metric = metric,
|
|
377
|
-
level_iters = [10000, 1000, 100],
|
|
378
|
-
sigmas = [3.0, 1.0, 0.0],
|
|
379
|
-
factors = [4, 2, 1],
|
|
380
|
-
)
|
|
381
|
-
transform = TranslationTransform3D()
|
|
382
|
-
params0 = None
|
|
383
|
-
mapping = affreg.optimize(fixed, moving, transform, params0)
|
|
384
|
-
|
|
385
|
-
# Warp the moving image
|
|
386
|
-
coregistered = mapping.transform(moving, 'linear')
|
|
387
|
-
|
|
388
|
-
return coregistered
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
def _coregister_affine_3d_arrays(fixed, moving):
|
|
395
|
-
|
|
396
|
-
metric = MutualInformationMetric(
|
|
397
|
-
nbins=32,
|
|
398
|
-
sampling_proportion=None,
|
|
399
|
-
)
|
|
400
|
-
affreg = AffineRegistration(
|
|
401
|
-
metric = metric,
|
|
402
|
-
level_iters = [10000, 1000, 100],
|
|
403
|
-
sigmas = [3.0, 1.0, 0.0],
|
|
404
|
-
factors = [4, 2, 1],
|
|
405
|
-
)
|
|
406
|
-
transform = AffineTransform3D()
|
|
407
|
-
params0 = None
|
|
408
|
-
mapping = affreg.optimize(fixed, moving, transform, params0)
|
|
409
|
-
|
|
410
|
-
# Warp the moving image
|
|
411
|
-
coregistered = mapping.transform(moving, 'linear')
|
|
412
|
-
|
|
413
|
-
return coregistered
|
|
414
|
-
|
|
415
|
-
|
|
416
403
|
def _coregister_arrays(fixed, moving, transformation='Symmetric Diffeomorphic', metric="Cross-Correlation"):
|
|
417
404
|
"""
|
|
418
405
|
Coregister two arrays and return coregistered + deformation field
|
|
419
406
|
"""
|
|
420
407
|
|
|
421
|
-
# Define the metric
|
|
422
408
|
dim = fixed.ndim
|
|
423
409
|
|
|
424
410
|
# 3D registration does not seem to work with smaller slabs
|