dbdicom 0.2.6__py3-none-any.whl → 0.3.0__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 +1 -28
- dbdicom/api.py +267 -0
- dbdicom/const.py +144 -0
- dbdicom/dataset.py +752 -0
- dbdicom/dbd.py +719 -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/register.py +527 -0
- dbdicom/{ds/types → sop_classes}/ct_image.py +2 -16
- dbdicom/{ds/types → sop_classes}/enhanced_mr_image.py +153 -26
- dbdicom/{ds/types → sop_classes}/mr_image.py +185 -140
- dbdicom/sop_classes/parametric_map.py +307 -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 +36 -0
- dbdicom/utils/files.py +0 -20
- dbdicom/utils/image.py +10 -629
- dbdicom-0.3.0.dist-info/METADATA +28 -0
- dbdicom-0.3.0.dist-info/RECORD +53 -0
- dbdicom/create.py +0 -457
- dbdicom/dro.py +0 -174
- dbdicom/ds/__init__.py +0 -10
- dbdicom/ds/create.py +0 -63
- dbdicom/ds/dataset.py +0 -869
- dbdicom/ds/dictionaries.py +0 -620
- dbdicom/ds/types/parametric_map.py +0 -226
- dbdicom/extensions/__init__.py +0 -9
- dbdicom/extensions/dipy.py +0 -448
- dbdicom/extensions/elastix.py +0 -503
- dbdicom/extensions/matplotlib.py +0 -107
- dbdicom/extensions/numpy.py +0 -271
- dbdicom/extensions/scipy.py +0 -1512
- dbdicom/extensions/skimage.py +0 -1030
- dbdicom/extensions/sklearn.py +0 -243
- dbdicom/extensions/vreg.py +0 -1390
- dbdicom/manager.py +0 -2132
- dbdicom/message.py +0 -119
- dbdicom/pipelines.py +0 -66
- dbdicom/record.py +0 -1893
- dbdicom/types/database.py +0 -107
- dbdicom/types/instance.py +0 -231
- dbdicom/types/patient.py +0 -40
- dbdicom/types/series.py +0 -2874
- dbdicom/types/study.py +0 -58
- dbdicom-0.2.6.dist-info/METADATA +0 -72
- dbdicom-0.2.6.dist-info/RECORD +0 -66
- {dbdicom-0.2.6.dist-info → dbdicom-0.3.0.dist-info}/WHEEL +0 -0
- {dbdicom-0.2.6.dist-info → dbdicom-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {dbdicom-0.2.6.dist-info → dbdicom-0.3.0.dist-info}/top_level.txt +0 -0
dbdicom/extensions/numpy.py
DELETED
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
``dbdicom`` extensions calling numpy functions. These do not require additional packages to be installed.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
import dbdicom as dbd
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def mean_intensity_projection(series:dbd.Series, dims=('SliceLocation','InstanceNumber'), axis=-1) -> dbd.Series:
|
|
10
|
-
"""Create a mean intensity projection along a specified dimension.
|
|
11
|
-
|
|
12
|
-
Args:
|
|
13
|
-
series (dbdicom.Series): Original series.
|
|
14
|
-
dims (tuple, optional): Dimensions of the array. Defaults to ('SliceLocation','InstanceNumber').
|
|
15
|
-
axis (int, optional): axis along which the maximum is to be taken. Defaults to -1.
|
|
16
|
-
|
|
17
|
-
Returns:
|
|
18
|
-
dbicom.Series: mean intensity projection.
|
|
19
|
-
|
|
20
|
-
Example:
|
|
21
|
-
|
|
22
|
-
Get the MIP function from the numpy extension to dbdicom:
|
|
23
|
-
|
|
24
|
-
>>> from db.extensions.numpy import mean_intensity_projection
|
|
25
|
-
|
|
26
|
-
Create a zero-filled array, describing 8 MRI images each measured at 3 flip angles and 2 repetition times:
|
|
27
|
-
|
|
28
|
-
>>> coords = {
|
|
29
|
-
... 'SliceLocation': np.arange(8),
|
|
30
|
-
... 'FlipAngle': [2, 15, 30],
|
|
31
|
-
... 'RepetitionTime': [2.5, 5.0],
|
|
32
|
-
... }
|
|
33
|
-
>>> series = db.zeros((128,128,8,3,2), coords)
|
|
34
|
-
|
|
35
|
-
Create a mean intensity projection on the slice locations and check the dimensions:
|
|
36
|
-
|
|
37
|
-
>>> mip = mean_intensity_projection(series)
|
|
38
|
-
>>> array = mip.pixel_values(dims=('SliceLocation', 'ImageNumber'))
|
|
39
|
-
>>> print(array.shape)
|
|
40
|
-
(128, 128, 8, 1)
|
|
41
|
-
|
|
42
|
-
Create a mean intensity projection along the Slice Location axis:
|
|
43
|
-
|
|
44
|
-
>>> mip = mean_intensity_projection(series, dims=tuple(coords), axis=0)
|
|
45
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
46
|
-
>>> print(array.shape)
|
|
47
|
-
(128, 128, 1, 3, 2)
|
|
48
|
-
|
|
49
|
-
Create a mean intensity projection along the Flip Angle axis:
|
|
50
|
-
|
|
51
|
-
>>> mip = mean_intensity_projection(series, dims=tuple(coords), axis=1)
|
|
52
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
53
|
-
>>> print(array.shape)
|
|
54
|
-
(128, 128, 8, 1, 2)
|
|
55
|
-
|
|
56
|
-
Create a mean intensity projection along the Repetition Time axis:
|
|
57
|
-
|
|
58
|
-
>>> mip = mean_intensity_projection(series, dims=tuple(coords), axis=2)
|
|
59
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
60
|
-
>>> print(array.shape)
|
|
61
|
-
(128, 128, 8, 3, 1)
|
|
62
|
-
"""
|
|
63
|
-
array = series.pixel_values(dims=dims)
|
|
64
|
-
array = np.mean(array, axis=axis)
|
|
65
|
-
|
|
66
|
-
# Save as DICOM
|
|
67
|
-
proj = series.new_sibling(SeriesDescription = series.SeriesDescription + '[mean axis ' + str(axis) + ']')
|
|
68
|
-
frames = series.frames(dims)
|
|
69
|
-
frames = np.take(frames, 0, axis=axis)
|
|
70
|
-
frames = frames.ravel()
|
|
71
|
-
array = array.reshape((array.shape[0], array.shape[1], -1))
|
|
72
|
-
for z in range(frames.size):
|
|
73
|
-
series.progress(z+1, frames.size, 'Saving results.. ')
|
|
74
|
-
frames_z = frames[z].copy_to(proj)
|
|
75
|
-
frames_z.set_pixel_values(array[:,:,z])
|
|
76
|
-
|
|
77
|
-
return proj
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def maximum_intensity_projection(series:dbd.Series, dims=('SliceLocation','InstanceNumber'), axis=-1) -> dbd.Series:
|
|
81
|
-
"""Create a maximum intensity projection along a specified dimension.
|
|
82
|
-
|
|
83
|
-
Args:
|
|
84
|
-
series (dbdicom.Series): Original series.
|
|
85
|
-
dims (tuple, optional): Dimensions of the array. Defaults to ('SliceLocation','InstanceNumber').
|
|
86
|
-
axis (int, optional): axis along which the maximum is to be taken. Defaults to -1.
|
|
87
|
-
|
|
88
|
-
Returns:
|
|
89
|
-
dbicom.Series: maximum intensity projection.
|
|
90
|
-
|
|
91
|
-
Example:
|
|
92
|
-
|
|
93
|
-
Get the MIP function from the numpy extension to dbdicom:
|
|
94
|
-
|
|
95
|
-
>>> from db.extensions.numpy import maximum_intensity_projection
|
|
96
|
-
|
|
97
|
-
Create a zero-filled array, describing 8 MRI images each measured at 3 flip angles and 2 repetition times:
|
|
98
|
-
|
|
99
|
-
>>> coords = {
|
|
100
|
-
... 'SliceLocation': np.arange(8),
|
|
101
|
-
... 'FlipAngle': [2, 15, 30],
|
|
102
|
-
... 'RepetitionTime': [2.5, 5.0],
|
|
103
|
-
... }
|
|
104
|
-
>>> series = db.zeros((128,128,8,3,2), coords)
|
|
105
|
-
|
|
106
|
-
Create a maximum intensity projection on the slice locations and check the dimensions:
|
|
107
|
-
|
|
108
|
-
>>> mip = maximum_intensity_projection(series)
|
|
109
|
-
>>> array = mip.pixel_values(dims=('SliceLocation', 'ImageNumber'))
|
|
110
|
-
>>> print(array.shape)
|
|
111
|
-
(128, 128, 8, 1)
|
|
112
|
-
|
|
113
|
-
Create a maximum intensity projection along the Slice Location axis:
|
|
114
|
-
|
|
115
|
-
>>> mip = maximum_intensity_projection(series, dims=tuple(coords), axis=0)
|
|
116
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
117
|
-
>>> print(array.shape)
|
|
118
|
-
(128, 128, 1, 3, 2)
|
|
119
|
-
|
|
120
|
-
Create a maximum intensity projection along the Flip Angle axis:
|
|
121
|
-
|
|
122
|
-
>>> mip = maximum_intensity_projection(series, dims=tuple(coords), axis=1)
|
|
123
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
124
|
-
>>> print(array.shape)
|
|
125
|
-
(128, 128, 8, 1, 2)
|
|
126
|
-
|
|
127
|
-
Create a maximum intensity projection along the Repetition Time axis:
|
|
128
|
-
|
|
129
|
-
>>> mip = maximum_intensity_projection(series, dims=tuple(coords), axis=2)
|
|
130
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
131
|
-
>>> print(array.shape)
|
|
132
|
-
(128, 128, 8, 3, 1)
|
|
133
|
-
"""
|
|
134
|
-
|
|
135
|
-
array = series.pixel_values(dims=dims)
|
|
136
|
-
array = np.amax(array, axis=axis)
|
|
137
|
-
|
|
138
|
-
# Save as DICOM
|
|
139
|
-
proj = series.new_sibling(SeriesDescription = series.SeriesDescription + '[max axis ' + str(axis) + ']')
|
|
140
|
-
frames = series.frames(dims)
|
|
141
|
-
frames = np.take(frames, 0, axis=axis)
|
|
142
|
-
frames = frames.ravel()
|
|
143
|
-
array = array.reshape((array.shape[0], array.shape[1], -1))
|
|
144
|
-
for z in range(frames.size):
|
|
145
|
-
series.progress(z+1, frames.size, 'Saving results.. ')
|
|
146
|
-
frames_z = frames[z].copy_to(proj)
|
|
147
|
-
frames_z.set_pixel_values(array[:,:,z])
|
|
148
|
-
|
|
149
|
-
return proj
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def norm_projection(series:dbd.Series, dims=('SliceLocation','InstanceNumber'), axis=-1, ord=None) -> dbd.Series:
|
|
153
|
-
"""Projection along a specified dimension using the vector norm.
|
|
154
|
-
|
|
155
|
-
This functions uses numpy.linalg.norm to calculate the projection, see: https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
series (dbdicom.Series): Original series.
|
|
159
|
-
dims (tuple, optional): Dimensions of the array. Defaults to ('SliceLocation','InstanceNumber').
|
|
160
|
-
axis (int, optional): axis along which the maximum is to be taken. Defaults to -1.
|
|
161
|
-
ord (int, optional): order of the norm - see documentation of numpy.linalg.norm for details
|
|
162
|
-
|
|
163
|
-
Returns:
|
|
164
|
-
dbicom.Series: maximum intensity projection.
|
|
165
|
-
|
|
166
|
-
Example:
|
|
167
|
-
|
|
168
|
-
Get the function from the numpy extension to dbdicom:
|
|
169
|
-
|
|
170
|
-
>>> from db.extensions.numpy import norm_projection
|
|
171
|
-
|
|
172
|
-
Create a zero-filled array, describing 8 MRI images each measured at 3 flip angles and 2 repetition times:
|
|
173
|
-
|
|
174
|
-
>>> coords = {
|
|
175
|
-
... 'SliceLocation': np.arange(8),
|
|
176
|
-
... 'FlipAngle': [2, 15, 30],
|
|
177
|
-
... 'RepetitionTime': [2.5, 5.0],
|
|
178
|
-
... }
|
|
179
|
-
>>> series = db.zeros((128,128,8,3,2), coords)
|
|
180
|
-
|
|
181
|
-
Create a norm projection on the slice locations and check the dimensions:
|
|
182
|
-
|
|
183
|
-
>>> mip = norm_projection(series)
|
|
184
|
-
>>> array = mip.pixel_values(dims=('SliceLocation', 'ImageNumber'))
|
|
185
|
-
>>> print(array.shape)
|
|
186
|
-
(128, 128, 8, 1)
|
|
187
|
-
|
|
188
|
-
Create a norm projection along the Slice Location axis:
|
|
189
|
-
|
|
190
|
-
>>> mip = norm_projection(series, dims=tuple(coords), axis=0)
|
|
191
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
192
|
-
>>> print(array.shape)
|
|
193
|
-
(128, 128, 1, 3, 2)
|
|
194
|
-
|
|
195
|
-
Create a norm projection along the Flip Angle axis:
|
|
196
|
-
|
|
197
|
-
>>> mip = norm_projection(series, dims=tuple(coords), axis=1)
|
|
198
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
199
|
-
>>> print(array.shape)
|
|
200
|
-
(128, 128, 8, 1, 2)
|
|
201
|
-
|
|
202
|
-
Create a norm projection along the Repetition Time axis:
|
|
203
|
-
|
|
204
|
-
>>> mip = norm_projection(series, dims=tuple(coords), axis=2)
|
|
205
|
-
>>> array = mip.pixel_values(dims=tuple(coords))
|
|
206
|
-
>>> print(array.shape)
|
|
207
|
-
(128, 128, 8, 3, 1)
|
|
208
|
-
"""
|
|
209
|
-
array = series.pixel_values(dims=dims)
|
|
210
|
-
array = np.linalg.norm(array, ord=ord, axis=axis)
|
|
211
|
-
|
|
212
|
-
# Save as DICOM
|
|
213
|
-
proj = series.new_sibling(SeriesDescription = series.SeriesDescription + '[norm axis ' + str(axis) + ']')
|
|
214
|
-
frames = series.frames(dims)
|
|
215
|
-
frames = np.take(frames, 0, axis=axis)
|
|
216
|
-
frames = frames.ravel()
|
|
217
|
-
array = array.reshape((array.shape[0], array.shape[1], -1))
|
|
218
|
-
for z in range(frames.size):
|
|
219
|
-
series.progress(z+1, frames.size, 'Saving results.. ')
|
|
220
|
-
frames_z = frames[z].copy_to(proj)
|
|
221
|
-
frames_z.set_pixel_values(array[:,:,z])
|
|
222
|
-
|
|
223
|
-
return proj
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
def threshold(input:dbd.Series, low_threshold=0, high_threshold=1, method='absolute')-> dbd.Series:
|
|
228
|
-
"""Create a mask series by thresholding.
|
|
229
|
-
|
|
230
|
-
Args:
|
|
231
|
-
input (dbd.Series): original data to be masked
|
|
232
|
-
low_threshold (int, optional): Lower threshold for masking. Defaults to 0.
|
|
233
|
-
high_threshold (int, optional): Upper threshold for masking. Defaults to 1.
|
|
234
|
-
method (str, optional): Type of thresholding, either 'absolute' (thresholds are absolute signal values), 'quantiles' (thresholds are quantiles), or 'range' (thresholds are between 0 and 1). Defaults to 'absolute'.
|
|
235
|
-
|
|
236
|
-
Returns:
|
|
237
|
-
dbd.Series: mask series with values = 1 inside and 0 outside.
|
|
238
|
-
"""
|
|
239
|
-
suffix = ' [Threshold segmentation]'
|
|
240
|
-
desc = input.instance().SeriesDescription
|
|
241
|
-
filtered = input.copy(SeriesDescription = desc+suffix)
|
|
242
|
-
#images = filtered.instances()
|
|
243
|
-
images = filtered.images()
|
|
244
|
-
for i, image in enumerate(images):
|
|
245
|
-
input.status.progress(i+1, len(images), 'Filtering ' + desc)
|
|
246
|
-
image.read()
|
|
247
|
-
array = image.array()
|
|
248
|
-
if method == 'quantiles':
|
|
249
|
-
range = np.quantile(array, [low_threshold, high_threshold])
|
|
250
|
-
elif method == 'range':
|
|
251
|
-
min, max = np.amin(array), np.amax(array)
|
|
252
|
-
range = [min+low_threshold*(max-min), min+high_threshold*(max-min)]
|
|
253
|
-
else:
|
|
254
|
-
range = [low_threshold, high_threshold]
|
|
255
|
-
array = np.logical_and(array > range[0], array < range[1])
|
|
256
|
-
image.set_array(array)
|
|
257
|
-
array = array.astype(np.ubyte)
|
|
258
|
-
_reset_window(image, array)
|
|
259
|
-
image.clear()
|
|
260
|
-
input.status.hide()
|
|
261
|
-
return filtered
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
# Helper functions
|
|
266
|
-
|
|
267
|
-
def _reset_window(image, array):
|
|
268
|
-
min = np.amin(array)
|
|
269
|
-
max = np.amax(array)
|
|
270
|
-
image.WindowCenter= (max+min)/2
|
|
271
|
-
image.WindowWidth = 0.9*(max-min)
|