dbdicom 0.2.0__py3-none-any.whl → 0.3.16__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.
- dbdicom/__init__.py +3 -25
- dbdicom/api.py +496 -0
- dbdicom/const.py +144 -0
- dbdicom/database.py +133 -0
- dbdicom/dataset.py +471 -0
- dbdicom/dbd.py +1290 -0
- dbdicom/external/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc +0 -0
- dbdicom/external/dcm4che/bin/emf2sf +57 -57
- dbdicom/register.py +402 -0
- dbdicom/{ds/types → sop_classes}/ct_image.py +2 -16
- dbdicom/{ds/types → sop_classes}/enhanced_mr_image.py +206 -160
- dbdicom/sop_classes/mr_image.py +338 -0
- dbdicom/sop_classes/parametric_map.py +381 -0
- dbdicom/sop_classes/secondary_capture.py +140 -0
- dbdicom/sop_classes/segmentation.py +311 -0
- dbdicom/{ds/types → sop_classes}/ultrasound_multiframe_image.py +1 -15
- dbdicom/{ds/types → sop_classes}/xray_angiographic_image.py +2 -17
- dbdicom/utils/arrays.py +142 -0
- dbdicom/utils/files.py +0 -20
- dbdicom/utils/image.py +43 -466
- dbdicom/utils/pydicom_dataset.py +386 -0
- dbdicom-0.3.16.dist-info/METADATA +26 -0
- dbdicom-0.3.16.dist-info/RECORD +54 -0
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/WHEEL +1 -1
- dbdicom/create.py +0 -450
- dbdicom/ds/__init__.py +0 -10
- dbdicom/ds/create.py +0 -63
- dbdicom/ds/dataset.py +0 -841
- dbdicom/ds/dictionaries.py +0 -620
- dbdicom/ds/types/mr_image.py +0 -267
- dbdicom/ds/types/parametric_map.py +0 -226
- 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/manager.py +0 -2077
- dbdicom/message.py +0 -119
- dbdicom/record.py +0 -1526
- dbdicom/types/database.py +0 -107
- dbdicom/types/instance.py +0 -184
- dbdicom/types/patient.py +0 -40
- dbdicom/types/series.py +0 -816
- dbdicom/types/study.py +0 -58
- dbdicom/utils/variables.py +0 -155
- dbdicom/utils/vreg.py +0 -2626
- dbdicom/wrappers/__init__.py +0 -7
- dbdicom/wrappers/dipy.py +0 -462
- dbdicom/wrappers/elastix.py +0 -855
- dbdicom/wrappers/numpy.py +0 -119
- dbdicom/wrappers/scipy.py +0 -1413
- dbdicom/wrappers/skimage.py +0 -1030
- dbdicom/wrappers/sklearn.py +0 -151
- dbdicom/wrappers/vreg.py +0 -273
- dbdicom-0.2.0.dist-info/METADATA +0 -276
- dbdicom-0.2.0.dist-info/RECORD +0 -81
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info/licenses}/LICENSE +0 -0
- {dbdicom-0.2.0.dist-info → dbdicom-0.3.16.dist-info}/top_level.txt +0 -0
dbdicom/wrappers/__init__.py
DELETED
dbdicom/wrappers/dipy.py
DELETED
|
@@ -1,462 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
|
|
3
|
-
from dipy.align.metrics import CCMetric, EMMetric, SSDMetric
|
|
4
|
-
from dipy.align.imaffine import MutualInformationMetric, AffineRegistration
|
|
5
|
-
from dipy.align.transforms import (TranslationTransform3D,
|
|
6
|
-
RigidTransform3D,
|
|
7
|
-
AffineTransform3D)
|
|
8
|
-
from dipy.align import center_of_mass
|
|
9
|
-
from dipy.align.vector_fields import (
|
|
10
|
-
warp_3d_nn,
|
|
11
|
-
warp_3d,
|
|
12
|
-
warp_2d_nn,
|
|
13
|
-
warp_2d,
|
|
14
|
-
invert_vector_field_fixed_point_3d,
|
|
15
|
-
invert_vector_field_fixed_point_2d,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
from dipy.segment.mask import median_otsu as median_otsu_np
|
|
19
|
-
import dbdicom.wrappers.scipy as scipy
|
|
20
|
-
from dbdicom.utils.image import slice_to_volume
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def median_otsu(series, **kwargs):
|
|
27
|
-
|
|
28
|
-
# Get arrays for fixed and moving series
|
|
29
|
-
array, headers = series.array('SliceLocation', pixels_first=True)
|
|
30
|
-
|
|
31
|
-
# Apply Otsu
|
|
32
|
-
mask = np.empty(array.shape)
|
|
33
|
-
cnt=0
|
|
34
|
-
for z in range(array.shape[2]):
|
|
35
|
-
for k in range(array.shape[3]):
|
|
36
|
-
cnt+=1
|
|
37
|
-
series.status.progress(cnt, array.shape[2]*array.shape[3], 'Applying Otsu segmentation..')
|
|
38
|
-
image = np.squeeze(array[:,:,z,k])
|
|
39
|
-
array[:,:,z,k], mask[:,:,z,k] = median_otsu_np(image, **kwargs)
|
|
40
|
-
|
|
41
|
-
# Create new series
|
|
42
|
-
masked_series = series.new_sibling(suffix='masked')
|
|
43
|
-
otsu_mask = series.new_sibling(suffix ='otsu mask')
|
|
44
|
-
|
|
45
|
-
# Set values and return
|
|
46
|
-
masked_series.set_array(array, headers, pixels_first=True)
|
|
47
|
-
otsu_mask.set_array(mask, headers, pixels_first=True)
|
|
48
|
-
return masked_series, otsu_mask
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def align_center_of_mass_3d(moving, fixed):
|
|
52
|
-
|
|
53
|
-
# Get arrays for fixed and moving series
|
|
54
|
-
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
55
|
-
array_fixed = scipy.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
56
|
-
|
|
57
|
-
# Coregister fixed and moving slice-by-slice
|
|
58
|
-
identity = np.eye(4)
|
|
59
|
-
array_moving, _ = center_of_mass(array_moving, array_fixed, static_affine=identity, moving_affine=identity)
|
|
60
|
-
|
|
61
|
-
# Create new series
|
|
62
|
-
moved = moving.new_sibling(suffix='aligned')
|
|
63
|
-
moved.set_array(array_moving, headers_moving, pixels_first=True)
|
|
64
|
-
|
|
65
|
-
return moved
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def coregister_translation_3d(moving, fixed):
|
|
69
|
-
|
|
70
|
-
# Get arrays for fixed and moving series
|
|
71
|
-
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
72
|
-
array_fixed = scipy.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
73
|
-
|
|
74
|
-
# Align images
|
|
75
|
-
moving.message('Performing coregistration..')
|
|
76
|
-
coregistered = _coregister_translation_3d_arrays(array_fixed, array_moving)
|
|
77
|
-
|
|
78
|
-
# Return as new series
|
|
79
|
-
coreg = moving.new_sibling(suffix='translated')
|
|
80
|
-
coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
81
|
-
|
|
82
|
-
return coreg
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def coregister_rigid_3d(moving, static, ignore_empty_slices=False):
|
|
86
|
-
|
|
87
|
-
# Get arrays for fixed and moving series
|
|
88
|
-
#array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
89
|
-
#array_static = scipy.array(static, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
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)
|
|
93
|
-
|
|
94
|
-
# Get masks if required - this feature not tested
|
|
95
|
-
if ignore_empty_slices:
|
|
96
|
-
moving_mask = _coregistration_mask_3d(array_moving)
|
|
97
|
-
static_mask = _coregistration_mask_3d(array_static)
|
|
98
|
-
else:
|
|
99
|
-
moving_mask = None
|
|
100
|
-
static_mask = None
|
|
101
|
-
|
|
102
|
-
# Align images
|
|
103
|
-
moving.message('Performing coregistration..')
|
|
104
|
-
coregistered = _coregister_rigid_3d_arrays(
|
|
105
|
-
array_static,
|
|
106
|
-
array_moving,
|
|
107
|
-
static_mask = static_mask,
|
|
108
|
-
moving_mask = moving_mask,
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
# Return as new series
|
|
112
|
-
# coreg = moving.new_sibling(suffix='rigid')
|
|
113
|
-
# coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
114
|
-
coreg = static.new_sibling(suffix='rigid')
|
|
115
|
-
coreg.set_array(coregistered, headers_static, pixels_first=True)
|
|
116
|
-
return coreg
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# Works but slices come out too thick
|
|
120
|
-
def WIP_coregister_rigid_3d(moving, static, ignore_empty_slices=False):
|
|
121
|
-
|
|
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
|
-
# 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
|
-
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
145
|
-
|
|
146
|
-
# If images are single-slice, expand into volumes
|
|
147
|
-
if array_moving.shape[2] == 1:
|
|
148
|
-
array_moving, affine_moving = slice_to_volume(array_moving, affine_moving)
|
|
149
|
-
if array_static.shape[2] == 1:
|
|
150
|
-
array_static, affine_static = slice_to_volume(array_static, affine_static)
|
|
151
|
-
|
|
152
|
-
# Get masks if required - this feature not tested
|
|
153
|
-
if ignore_empty_slices:
|
|
154
|
-
moving_mask = _coregistration_mask_3d(array_moving)
|
|
155
|
-
static_mask = _coregistration_mask_3d(array_static)
|
|
156
|
-
else:
|
|
157
|
-
moving_mask = None
|
|
158
|
-
static_mask = None
|
|
159
|
-
|
|
160
|
-
# Align images
|
|
161
|
-
moving.message('Performing coregistration..')
|
|
162
|
-
coregistered = _coregister_rigid_3d_arrays(
|
|
163
|
-
array_static,
|
|
164
|
-
array_moving,
|
|
165
|
-
static_grid2world = affine_static,
|
|
166
|
-
moving_grid2world = affine_moving,
|
|
167
|
-
static_mask = static_mask,
|
|
168
|
-
moving_mask = moving_mask,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
# Return as new series
|
|
172
|
-
# coreg = moving.new_sibling(suffix='rigid')
|
|
173
|
-
# coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
174
|
-
coreg = static.new_sibling(suffix='rigid')
|
|
175
|
-
coreg.set_array(coregistered, headers_static, pixels_first=True)
|
|
176
|
-
return coreg
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def _coregister_rigid_3d_arrays(static, moving, **kwargs):
|
|
180
|
-
|
|
181
|
-
metric = MutualInformationMetric(
|
|
182
|
-
nbins=32,
|
|
183
|
-
sampling_proportion=None,
|
|
184
|
-
)
|
|
185
|
-
affreg = AffineRegistration(
|
|
186
|
-
metric = metric,
|
|
187
|
-
level_iters = [10000, 1000, 100],
|
|
188
|
-
sigmas = [3.0, 1.0, 0.0],
|
|
189
|
-
factors = [4, 2, 1],
|
|
190
|
-
)
|
|
191
|
-
transform = RigidTransform3D()
|
|
192
|
-
params0 = None
|
|
193
|
-
mapping = affreg.optimize(static, moving, transform, params0, **kwargs)
|
|
194
|
-
|
|
195
|
-
# Warp the moving image
|
|
196
|
-
coregistered = mapping.transform(moving, 'linear')
|
|
197
|
-
|
|
198
|
-
return coregistered
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def coregister_affine_3d(moving, fixed):
|
|
202
|
-
|
|
203
|
-
# Get arrays for fixed and moving series
|
|
204
|
-
array_moving, headers_moving = moving.array(sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
205
|
-
array_fixed = scipy.array(fixed, on=moving, sortby='SliceLocation', pixels_first=True, first_volume=True)
|
|
206
|
-
|
|
207
|
-
# Align images
|
|
208
|
-
moving.message('Performing coregistration..')
|
|
209
|
-
coregistered = _coregister_affine_3d_arrays(array_fixed, array_moving)
|
|
210
|
-
|
|
211
|
-
# Return as new series
|
|
212
|
-
coreg = moving.new_sibling(suffix='affine')
|
|
213
|
-
coreg.set_array(coregistered, headers_moving, pixels_first=True)
|
|
214
|
-
|
|
215
|
-
return coreg
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def coregister_2d_to_2d(moving, fixed, **kwargs):
|
|
219
|
-
|
|
220
|
-
# Overlay fixed on moving image
|
|
221
|
-
fixed_map = scipy.map_to(fixed, moving)
|
|
222
|
-
|
|
223
|
-
# Get arrays for fixed and moving series
|
|
224
|
-
array_fixed, _ = fixed_map.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
225
|
-
array_moving, headers_moving = moving.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
226
|
-
|
|
227
|
-
# Remove overlay from database
|
|
228
|
-
if fixed_map != fixed:
|
|
229
|
-
fixed_map.remove()
|
|
230
|
-
|
|
231
|
-
# Coregister fixed and moving slice-by-slice
|
|
232
|
-
deformation = np.empty(array_moving.shape + (2,))
|
|
233
|
-
for z in range(array_moving.shape[2]):
|
|
234
|
-
moving.status.progress(z+1, array_moving.shape[2], 'Performing coregistration..')
|
|
235
|
-
coreg, deform = _coregister_arrays(array_fixed[:,:,z], array_moving[:,:,z], **kwargs)
|
|
236
|
-
array_moving[:,:,z] = coreg
|
|
237
|
-
deformation[:,:,z,:] = deform
|
|
238
|
-
|
|
239
|
-
# Create new series
|
|
240
|
-
coreg = moving.new_sibling(suffix= 'registered')
|
|
241
|
-
deform = moving.new_sibling(suffix='deformation field')
|
|
242
|
-
|
|
243
|
-
# Set values & return
|
|
244
|
-
coreg.set_array(array_moving, headers_moving, pixels_first=True)
|
|
245
|
-
for dim in range(deformation.shape[-1]):
|
|
246
|
-
deform.set_array(deformation[...,dim], headers_moving, pixels_first=True)
|
|
247
|
-
return coreg, deform
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def invert_deformation_field(deformation_field, **kwargs):
|
|
282
|
-
|
|
283
|
-
# Get array
|
|
284
|
-
array, headers = deformation_field.array('SliceLocation', pixels_first=True)
|
|
285
|
-
|
|
286
|
-
# Invert
|
|
287
|
-
array = _invert_deformation_field_array(array, deformation_field.status, **kwargs)
|
|
288
|
-
|
|
289
|
-
# Create new series
|
|
290
|
-
inv = deformation_field.new_sibling(suffix='inverse')
|
|
291
|
-
inv.set_array(array, headers, pixels_first=True)
|
|
292
|
-
|
|
293
|
-
return inv
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
def warp(image, deformation_field, **kwargs):
|
|
297
|
-
|
|
298
|
-
# Overlay deformation field on image
|
|
299
|
-
deform = scipy.map_to(deformation_field, image)
|
|
300
|
-
|
|
301
|
-
# Get arrays
|
|
302
|
-
array, headers = image.array('SliceLocation', pixels_first=True, first_volume=True)
|
|
303
|
-
array_deform, _ = deform.array('SliceLocation', pixels_first=True)
|
|
304
|
-
|
|
305
|
-
# Remove temporary variables
|
|
306
|
-
if deform != deformation_field:
|
|
307
|
-
deform.remove()
|
|
308
|
-
|
|
309
|
-
# Perform warping
|
|
310
|
-
array = _warp_array(array, array_deform, image.status, **kwargs)
|
|
311
|
-
|
|
312
|
-
# Create new series
|
|
313
|
-
warped = image.new_sibling(suffix='warped')
|
|
314
|
-
warped.set_array(array, headers, pixels_first=True)
|
|
315
|
-
|
|
316
|
-
return warped
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def _coregistration_mask_3d(array):
|
|
320
|
-
mask = np.zeros(array.shape)
|
|
321
|
-
for z in range(array.shape[2]):
|
|
322
|
-
if np.count_nonzero(array[:,:,z]) > 0:
|
|
323
|
-
mask[:,:,z] = 1
|
|
324
|
-
return mask
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
def _invert_deformation_field_array(array, status, max_iter=10, tolerance=0.1):
|
|
328
|
-
status.message('Inverting deformation field..')
|
|
329
|
-
dim = array.shape[-1]
|
|
330
|
-
d_world2grid = np.eye(dim+1)
|
|
331
|
-
spacing = np.ones(dim)
|
|
332
|
-
if dim==3:
|
|
333
|
-
return invert_vector_field_fixed_point_3d(array, d_world2grid, spacing, max_iter, tolerance)
|
|
334
|
-
elif dim==2:
|
|
335
|
-
nslices = array.shape[2]
|
|
336
|
-
for z in range(nslices):
|
|
337
|
-
status.progress(z+1, nslices, 'Inverting deformation field..')
|
|
338
|
-
array[:,:,z] = invert_vector_field_fixed_point_2d(array[:,:,z], d_world2grid, spacing, max_iter, tolerance)
|
|
339
|
-
return array
|
|
340
|
-
else:
|
|
341
|
-
msg = 'This series is not a deformation field.'
|
|
342
|
-
msg += 'A deformation field must have either 2 or 3 components.'
|
|
343
|
-
raise ValueError(msg)
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
def _warp_array(array, deform, status, interpolate=True):
|
|
347
|
-
status.message('Warping array..')
|
|
348
|
-
dim = deform.shape[-1]
|
|
349
|
-
if dim==3:
|
|
350
|
-
if interpolate:
|
|
351
|
-
return warp_3d(array, deform)
|
|
352
|
-
else:
|
|
353
|
-
return warp_3d_nn(array, deform)
|
|
354
|
-
elif dim==2:
|
|
355
|
-
nslices = deform.shape[2]
|
|
356
|
-
for z in range(nslices):
|
|
357
|
-
status.progress(z+1, nslices, 'Warping array..')
|
|
358
|
-
if interpolate:
|
|
359
|
-
array[:,:,z] = warp_2d(array[:,:,z], deform[:,:,z,:])
|
|
360
|
-
else:
|
|
361
|
-
array[:,:,z] = warp_2d_nn(array[:,:,z], deform[:,:,z,:])
|
|
362
|
-
return array
|
|
363
|
-
else:
|
|
364
|
-
msg = 'This series is not a deformation field.'
|
|
365
|
-
msg += 'A deformation field must have either 2 or 3 components.'
|
|
366
|
-
raise ValueError(msg)
|
|
367
|
-
|
|
368
|
-
|
|
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
|
-
def _coregister_arrays(fixed, moving, transformation='Symmetric Diffeomorphic', metric="Cross-Correlation"):
|
|
417
|
-
"""
|
|
418
|
-
Coregister two arrays and return coregistered + deformation field
|
|
419
|
-
"""
|
|
420
|
-
|
|
421
|
-
# Define the metric
|
|
422
|
-
dim = fixed.ndim
|
|
423
|
-
|
|
424
|
-
# 3D registration does not seem to work with smaller slabs
|
|
425
|
-
# Exclude this case
|
|
426
|
-
if dim == 3:
|
|
427
|
-
if fixed.shape[-1] < 6:
|
|
428
|
-
msg = 'The 3D volume does not have enough slices for 3D registration. \n'
|
|
429
|
-
msg += 'Try 2D registration instead.'
|
|
430
|
-
raise ValueError(msg)
|
|
431
|
-
|
|
432
|
-
# Define the metric
|
|
433
|
-
if metric == "Cross-Correlation":
|
|
434
|
-
sigma_diff = 3.0 # Gaussian Kernel
|
|
435
|
-
radius = 4 # Window for local CC
|
|
436
|
-
metric = CCMetric(dim, sigma_diff, radius)
|
|
437
|
-
elif metric == 'Expectation-Maximization':
|
|
438
|
-
metric = EMMetric(dim, smooth=1.0)
|
|
439
|
-
elif metric == 'Sum of Squared Differences':
|
|
440
|
-
metric = SSDMetric(dim, smooth=4.0)
|
|
441
|
-
else:
|
|
442
|
-
msg = 'The metric ' + metric + ' is currently not implemented.'
|
|
443
|
-
raise ValueError(msg)
|
|
444
|
-
|
|
445
|
-
# Define the deformation model
|
|
446
|
-
if transformation == 'Symmetric Diffeomorphic':
|
|
447
|
-
level_iters = [200, 100, 50, 25]
|
|
448
|
-
sdr = SymmetricDiffeomorphicRegistration(metric, level_iters, inv_iter=50)
|
|
449
|
-
else:
|
|
450
|
-
msg = 'The transform ' + transformation + ' is currently not implemented.'
|
|
451
|
-
raise ValueError(msg)
|
|
452
|
-
|
|
453
|
-
# Perform the optimization, return a DiffeomorphicMap object
|
|
454
|
-
mapping = sdr.optimize(fixed, moving)
|
|
455
|
-
|
|
456
|
-
# Get forward deformation field
|
|
457
|
-
deformation_field = mapping.get_forward_field()
|
|
458
|
-
|
|
459
|
-
# Warp the moving image
|
|
460
|
-
warped_moving = mapping.transform(moving, 'linear')
|
|
461
|
-
|
|
462
|
-
return warped_moving, deformation_field
|