dbdicom 0.3.0__py3-none-any.whl → 0.3.2__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/api.py +53 -10
- dbdicom/database.py +122 -0
- dbdicom/dataset.py +22 -71
- dbdicom/dbd.py +124 -182
- 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 +315 -234
- dbdicom/sop_classes/mr_image.py +122 -130
- dbdicom/sop_classes/parametric_map.py +94 -20
- dbdicom/utils/image.py +7 -6
- {dbdicom-0.3.0.dist-info → dbdicom-0.3.2.dist-info}/METADATA +2 -4
- {dbdicom-0.3.0.dist-info → dbdicom-0.3.2.dist-info}/RECORD +16 -15
- {dbdicom-0.3.0.dist-info → dbdicom-0.3.2.dist-info}/WHEEL +1 -1
- {dbdicom-0.3.0.dist-info → dbdicom-0.3.2.dist-info}/licenses/LICENSE +0 -0
- {dbdicom-0.3.0.dist-info → dbdicom-0.3.2.dist-info}/top_level.txt +0 -0
dbdicom/sop_classes/mr_image.py
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
# Coded version of DICOM file
|
|
2
|
-
# 'RIDER Neuro MRI-3369019796\03-21-1904-BRAINRESEARCH-00598\14.000000-sag 3d gre c-04769\1-010.dcm'
|
|
3
|
-
# Produced by pydicom codify utility script
|
|
4
1
|
import os
|
|
5
|
-
|
|
2
|
+
|
|
6
3
|
import numpy as np
|
|
7
4
|
import pydicom
|
|
8
5
|
from pydicom.dataset import FileMetaDataset, Dataset, FileDataset
|
|
@@ -14,7 +11,6 @@ from pydicom.uid import (
|
|
|
14
11
|
)
|
|
15
12
|
|
|
16
13
|
from datetime import datetime
|
|
17
|
-
import tempfile
|
|
18
14
|
|
|
19
15
|
import dbdicom.utils.image as image
|
|
20
16
|
|
|
@@ -22,11 +18,6 @@ import dbdicom.utils.image as image
|
|
|
22
18
|
def pixel_data(ds):
|
|
23
19
|
"""Read the pixel array from an MR image"""
|
|
24
20
|
|
|
25
|
-
#array = ds.pixel_array.astype(np.float64)
|
|
26
|
-
#array = ds.pixel_array
|
|
27
|
-
#array = np.frombuffer(ds.PixelData, dtype=np.uint16).reshape(ds.Rows, ds.Columns)
|
|
28
|
-
#array = array.astype(np.float32)
|
|
29
|
-
|
|
30
21
|
array = ds.pixel_array
|
|
31
22
|
array = array.astype(np.float32)
|
|
32
23
|
if [0x2005, 0x100E] in ds: # 'Philips Rescale Slope'
|
|
@@ -64,126 +55,6 @@ def set_pixel_data(ds, array):
|
|
|
64
55
|
ds.PixelData = array.tobytes()
|
|
65
56
|
|
|
66
57
|
|
|
67
|
-
|
|
68
|
-
def chat_gpt_3d(num_frames=10, rows=256, columns=256):
|
|
69
|
-
|
|
70
|
-
# File meta info
|
|
71
|
-
file_meta = FileMetaDataset()
|
|
72
|
-
file_meta.MediaStorageSOPClassUID = MRImageStorage
|
|
73
|
-
file_meta.MediaStorageSOPInstanceUID = generate_uid()
|
|
74
|
-
file_meta.ImplementationClassUID = generate_uid()
|
|
75
|
-
file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
|
|
76
|
-
|
|
77
|
-
# Create FileDataset in memory
|
|
78
|
-
ds = FileDataset(
|
|
79
|
-
filename_or_obj=None,
|
|
80
|
-
dataset=Dataset(),
|
|
81
|
-
file_meta=file_meta,
|
|
82
|
-
preamble=b"\0" * 128,
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
# Transfer syntax
|
|
86
|
-
ds.is_little_endian = True
|
|
87
|
-
ds.is_implicit_VR = False
|
|
88
|
-
|
|
89
|
-
now = datetime.now()
|
|
90
|
-
|
|
91
|
-
# Required fields
|
|
92
|
-
ds.SOPClassUID = MRImageStorage
|
|
93
|
-
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
|
|
94
|
-
ds.PatientName = "Multi^Frame"
|
|
95
|
-
ds.PatientID = "999999"
|
|
96
|
-
ds.StudyInstanceUID = generate_uid()
|
|
97
|
-
ds.SeriesInstanceUID = generate_uid()
|
|
98
|
-
ds.StudyDate = now.strftime("%Y%m%d")
|
|
99
|
-
ds.StudyTime = now.strftime("%H%M%S")
|
|
100
|
-
ds.Modality = "MR"
|
|
101
|
-
ds.Manufacturer = "PythonPACS"
|
|
102
|
-
ds.StudyID = "1"
|
|
103
|
-
ds.SeriesNumber = "1"
|
|
104
|
-
ds.InstanceNumber = "1"
|
|
105
|
-
|
|
106
|
-
# Image geometry
|
|
107
|
-
ds.Rows = rows
|
|
108
|
-
ds.Columns = columns
|
|
109
|
-
ds.PixelSpacing = [1.0, 1.0]
|
|
110
|
-
ds.ImagePositionPatient = [0.0, 0.0, 0.0]
|
|
111
|
-
ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
|
112
|
-
ds.FrameOfReferenceUID = generate_uid()
|
|
113
|
-
ds.PositionReferenceIndicator = ""
|
|
114
|
-
|
|
115
|
-
# Multi-frame specific
|
|
116
|
-
ds.NumberOfFrames = str(num_frames)
|
|
117
|
-
ds.InstanceNumber = "1"
|
|
118
|
-
|
|
119
|
-
# Pixel data requirements
|
|
120
|
-
ds.SamplesPerPixel = 1
|
|
121
|
-
ds.PhotometricInterpretation = "MONOCHROME2"
|
|
122
|
-
ds.BitsAllocated = 16
|
|
123
|
-
ds.BitsStored = 12
|
|
124
|
-
ds.HighBit = 11
|
|
125
|
-
ds.PixelRepresentation = 0 # unsigned
|
|
126
|
-
|
|
127
|
-
# Create dummy image data (e.g., black frames)
|
|
128
|
-
pixel_array = np.zeros((num_frames, rows, columns), dtype=np.uint16)
|
|
129
|
-
ds.PixelData = pixel_array.tobytes()
|
|
130
|
-
|
|
131
|
-
return ds
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def chat_gpt_2d():
|
|
136
|
-
# Basic identifiers
|
|
137
|
-
file_meta = FileMetaDataset()
|
|
138
|
-
file_meta.MediaStorageSOPClassUID = MRImageStorage
|
|
139
|
-
file_meta.MediaStorageSOPInstanceUID = generate_uid()
|
|
140
|
-
file_meta.ImplementationClassUID = generate_uid()
|
|
141
|
-
|
|
142
|
-
# Create the main dataset
|
|
143
|
-
ds = FileDataset(
|
|
144
|
-
filename_or_obj=None,
|
|
145
|
-
dataset=Dataset(),
|
|
146
|
-
file_meta=file_meta,
|
|
147
|
-
preamble=b"\0" * 128,
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
# Set transfer syntax
|
|
151
|
-
ds.is_little_endian = True
|
|
152
|
-
ds.is_implicit_VR = False
|
|
153
|
-
|
|
154
|
-
# Required DICOM tags for MR Image Storage
|
|
155
|
-
now = datetime.now()
|
|
156
|
-
ds.SOPClassUID = MRImageStorage
|
|
157
|
-
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
|
|
158
|
-
ds.PatientName = "Anonymous^Patient"
|
|
159
|
-
ds.PatientID = "123456"
|
|
160
|
-
ds.StudyInstanceUID = generate_uid()
|
|
161
|
-
ds.SeriesInstanceUID = generate_uid()
|
|
162
|
-
ds.StudyDate = now.strftime("%Y%m%d")
|
|
163
|
-
ds.StudyTime = now.strftime("%H%M%S")
|
|
164
|
-
ds.Modality = "MR"
|
|
165
|
-
ds.Manufacturer = "PythonPACS"
|
|
166
|
-
ds.StudyID = "1"
|
|
167
|
-
ds.SeriesNumber = "1"
|
|
168
|
-
ds.InstanceNumber = "1"
|
|
169
|
-
ds.ImagePositionPatient = [0.0, 0.0, 0.0]
|
|
170
|
-
ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
|
171
|
-
ds.FrameOfReferenceUID = generate_uid()
|
|
172
|
-
ds.PositionReferenceIndicator = ""
|
|
173
|
-
ds.Rows = 256
|
|
174
|
-
ds.Columns = 256
|
|
175
|
-
ds.PixelSpacing = [1.0, 1.0]
|
|
176
|
-
ds.BitsAllocated = 16
|
|
177
|
-
ds.BitsStored = 12
|
|
178
|
-
ds.HighBit = 11
|
|
179
|
-
ds.PixelRepresentation = 0 # unsigned
|
|
180
|
-
ds.SamplesPerPixel = 1
|
|
181
|
-
ds.PhotometricInterpretation = "MONOCHROME2"
|
|
182
|
-
ds.PixelData = (b"\0" * (ds.Rows * ds.Columns * 2)) # Dummy black image
|
|
183
|
-
|
|
184
|
-
return ds
|
|
185
|
-
|
|
186
|
-
|
|
187
58
|
def default(): # from the RIDER dataset
|
|
188
59
|
|
|
189
60
|
# File meta info data elements
|
|
@@ -309,6 +180,127 @@ def default(): # from the RIDER dataset
|
|
|
309
180
|
return ds
|
|
310
181
|
|
|
311
182
|
|
|
183
|
+
def chat_gpt_3d(num_frames=10, rows=256, columns=256):
|
|
184
|
+
|
|
185
|
+
# File meta info
|
|
186
|
+
file_meta = FileMetaDataset()
|
|
187
|
+
file_meta.MediaStorageSOPClassUID = MRImageStorage
|
|
188
|
+
file_meta.MediaStorageSOPInstanceUID = generate_uid()
|
|
189
|
+
file_meta.ImplementationClassUID = generate_uid()
|
|
190
|
+
file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
|
|
191
|
+
|
|
192
|
+
# Create FileDataset in memory
|
|
193
|
+
ds = FileDataset(
|
|
194
|
+
filename_or_obj=None,
|
|
195
|
+
dataset=Dataset(),
|
|
196
|
+
file_meta=file_meta,
|
|
197
|
+
preamble=b"\0" * 128,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Transfer syntax
|
|
201
|
+
ds.is_little_endian = True
|
|
202
|
+
ds.is_implicit_VR = False
|
|
203
|
+
|
|
204
|
+
now = datetime.now()
|
|
205
|
+
|
|
206
|
+
# Required fields
|
|
207
|
+
ds.SOPClassUID = MRImageStorage
|
|
208
|
+
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
|
|
209
|
+
ds.PatientName = "Multi^Frame"
|
|
210
|
+
ds.PatientID = "999999"
|
|
211
|
+
ds.StudyInstanceUID = generate_uid()
|
|
212
|
+
ds.SeriesInstanceUID = generate_uid()
|
|
213
|
+
ds.StudyDate = now.strftime("%Y%m%d")
|
|
214
|
+
ds.StudyTime = now.strftime("%H%M%S")
|
|
215
|
+
ds.Modality = "MR"
|
|
216
|
+
ds.Manufacturer = "PythonPACS"
|
|
217
|
+
ds.StudyID = "1"
|
|
218
|
+
ds.SeriesNumber = "1"
|
|
219
|
+
ds.InstanceNumber = "1"
|
|
220
|
+
|
|
221
|
+
# Image geometry
|
|
222
|
+
ds.Rows = rows
|
|
223
|
+
ds.Columns = columns
|
|
224
|
+
ds.PixelSpacing = [1.0, 1.0]
|
|
225
|
+
ds.ImagePositionPatient = [0.0, 0.0, 0.0]
|
|
226
|
+
ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
|
227
|
+
ds.FrameOfReferenceUID = generate_uid()
|
|
228
|
+
ds.PositionReferenceIndicator = ""
|
|
229
|
+
|
|
230
|
+
# Multi-frame specific
|
|
231
|
+
ds.NumberOfFrames = str(num_frames)
|
|
232
|
+
ds.InstanceNumber = "1"
|
|
233
|
+
|
|
234
|
+
# Pixel data requirements
|
|
235
|
+
ds.SamplesPerPixel = 1
|
|
236
|
+
ds.PhotometricInterpretation = "MONOCHROME2"
|
|
237
|
+
ds.BitsAllocated = 16
|
|
238
|
+
ds.BitsStored = 12
|
|
239
|
+
ds.HighBit = 11
|
|
240
|
+
ds.PixelRepresentation = 0 # unsigned
|
|
241
|
+
|
|
242
|
+
# Create dummy image data (e.g., black frames)
|
|
243
|
+
pixel_array = np.zeros((num_frames, rows, columns), dtype=np.uint16)
|
|
244
|
+
ds.PixelData = pixel_array.tobytes()
|
|
245
|
+
|
|
246
|
+
return ds
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def chat_gpt_2d():
|
|
251
|
+
# Basic identifiers
|
|
252
|
+
file_meta = FileMetaDataset()
|
|
253
|
+
file_meta.MediaStorageSOPClassUID = MRImageStorage
|
|
254
|
+
file_meta.MediaStorageSOPInstanceUID = generate_uid()
|
|
255
|
+
file_meta.ImplementationClassUID = generate_uid()
|
|
256
|
+
|
|
257
|
+
# Create the main dataset
|
|
258
|
+
ds = FileDataset(
|
|
259
|
+
filename_or_obj=None,
|
|
260
|
+
dataset=Dataset(),
|
|
261
|
+
file_meta=file_meta,
|
|
262
|
+
preamble=b"\0" * 128,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
# Set transfer syntax
|
|
266
|
+
ds.is_little_endian = True
|
|
267
|
+
ds.is_implicit_VR = False
|
|
268
|
+
|
|
269
|
+
# Required DICOM tags for MR Image Storage
|
|
270
|
+
now = datetime.now()
|
|
271
|
+
ds.SOPClassUID = MRImageStorage
|
|
272
|
+
ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
|
|
273
|
+
ds.PatientName = "Anonymous^Patient"
|
|
274
|
+
ds.PatientID = "123456"
|
|
275
|
+
ds.StudyInstanceUID = generate_uid()
|
|
276
|
+
ds.SeriesInstanceUID = generate_uid()
|
|
277
|
+
ds.StudyDate = now.strftime("%Y%m%d")
|
|
278
|
+
ds.StudyTime = now.strftime("%H%M%S")
|
|
279
|
+
ds.Modality = "MR"
|
|
280
|
+
ds.Manufacturer = "PythonPACS"
|
|
281
|
+
ds.StudyID = "1"
|
|
282
|
+
ds.SeriesNumber = "1"
|
|
283
|
+
ds.InstanceNumber = "1"
|
|
284
|
+
ds.ImagePositionPatient = [0.0, 0.0, 0.0]
|
|
285
|
+
ds.ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
|
286
|
+
ds.FrameOfReferenceUID = generate_uid()
|
|
287
|
+
ds.PositionReferenceIndicator = ""
|
|
288
|
+
ds.Rows = 256
|
|
289
|
+
ds.Columns = 256
|
|
290
|
+
ds.PixelSpacing = [1.0, 1.0]
|
|
291
|
+
ds.BitsAllocated = 16
|
|
292
|
+
ds.BitsStored = 12
|
|
293
|
+
ds.HighBit = 11
|
|
294
|
+
ds.PixelRepresentation = 0 # unsigned
|
|
295
|
+
ds.SamplesPerPixel = 1
|
|
296
|
+
ds.PhotometricInterpretation = "MONOCHROME2"
|
|
297
|
+
ds.PixelData = (b"\0" * (ds.Rows * ds.Columns * 2)) # Dummy black image
|
|
298
|
+
|
|
299
|
+
return ds
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
312
304
|
|
|
313
305
|
|
|
314
306
|
|
|
@@ -7,9 +7,11 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
def default():
|
|
11
|
+
|
|
12
|
+
rows=16
|
|
13
|
+
cols=16
|
|
14
|
+
frames=1
|
|
13
15
|
|
|
14
16
|
# File Meta Information
|
|
15
17
|
file_meta = Dataset()
|
|
@@ -32,8 +34,11 @@ def create_parametric_map(rows=64, cols=64, frames=1):
|
|
|
32
34
|
ds.PatientID = "123456"
|
|
33
35
|
ds.StudyDate = datetime.now().strftime("%Y%m%d")
|
|
34
36
|
ds.StudyTime = datetime.now().strftime("%H%M%S")
|
|
37
|
+
ds.ContentDate = datetime.now().strftime("%Y%m%d")
|
|
38
|
+
ds.ContentTime = datetime.now().strftime("%H%M%S")
|
|
35
39
|
ds.Modality = "OT"
|
|
36
40
|
ds.Manufacturer = "SyntheticGenerator"
|
|
41
|
+
ds.SeriesDescription = 'Minimal parametric map'
|
|
37
42
|
|
|
38
43
|
# General Image
|
|
39
44
|
ds.SeriesNumber = 1
|
|
@@ -43,38 +48,107 @@ def create_parametric_map(rows=64, cols=64, frames=1):
|
|
|
43
48
|
ds.ImageType = ['DERIVED', 'PRIMARY']
|
|
44
49
|
ds.ContentLabel = "PMAP"
|
|
45
50
|
ds.ContentDescription = "Synthetic Parametric Map"
|
|
46
|
-
ds.ContentCreatorName = "
|
|
51
|
+
ds.ContentCreatorName = "dbdicom"
|
|
47
52
|
|
|
48
53
|
# Pixel Data
|
|
49
|
-
ds.Rows = rows
|
|
50
|
-
ds.Columns = cols
|
|
51
54
|
ds.NumberOfFrames = frames
|
|
52
|
-
ds.PixelData = pixel_array.tobytes()
|
|
53
55
|
ds.SamplesPerPixel = 1
|
|
54
56
|
ds.PhotometricInterpretation = "MONOCHROME2"
|
|
57
|
+
|
|
58
|
+
ds.Rows = rows
|
|
59
|
+
ds.Columns = cols
|
|
55
60
|
ds.BitsAllocated = 32
|
|
56
61
|
ds.BitsStored = 32
|
|
57
62
|
ds.HighBit = 31
|
|
58
63
|
ds.PixelRepresentation = 1 # 1 = signed, 0 = unsigned
|
|
59
|
-
ds.FloatPixelData =
|
|
60
|
-
ds.PixelData =
|
|
64
|
+
ds.FloatPixelData = np.zeros((rows, cols), dtype=np.float32).tobytes()
|
|
65
|
+
#ds.PixelData = np.zeros((rows, cols), dtype=np.int16).tobytes()
|
|
66
|
+
|
|
67
|
+
# Required Parametric Map Attributes
|
|
68
|
+
ds.PixelMeasuresSequence = [Dataset()]
|
|
69
|
+
ds.PixelMeasuresSequence[0].SliceThickness = 1.0
|
|
70
|
+
ds.PixelMeasuresSequence[0].PixelSpacing = [1.0, 1.0]
|
|
71
|
+
|
|
72
|
+
ds.FrameOfReferenceUID = pydicom.uid.generate_uid()
|
|
61
73
|
|
|
62
74
|
# Functional Group Sequences (minimal dummy values)
|
|
63
75
|
ds.SharedFunctionalGroupsSequence = [Dataset()]
|
|
64
|
-
ds.
|
|
76
|
+
ds.SharedFunctionalGroupsSequence[0].PixelMeasuresSequence = [Dataset()]
|
|
77
|
+
ds.SharedFunctionalGroupsSequence[0].PixelMeasuresSequence[0].PixelSpacing = [1.0, 1.0]
|
|
78
|
+
ds.SharedFunctionalGroupsSequence[0].PlaneOrientationSequence = [Dataset()]
|
|
79
|
+
ds.SharedFunctionalGroupsSequence[0].PlaneOrientationSequence[0].ImageOrientationPatient = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]
|
|
80
|
+
|
|
81
|
+
ds.PerFrameFunctionalGroupsSequence = []
|
|
82
|
+
for i in range(ds.NumberOfFrames):
|
|
83
|
+
frame = Dataset()
|
|
84
|
+
frame.PlanePositionSequence = [Dataset()]
|
|
85
|
+
frame.PlanePositionSequence[0].ImagePositionPatient = [0.0, 0.0, float(i)]
|
|
86
|
+
ds.PerFrameFunctionalGroupsSequence.append(frame)
|
|
87
|
+
|
|
88
|
+
return ds
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def set_pixel_data(ds, array):
|
|
93
|
+
|
|
94
|
+
array = np.transpose(array)
|
|
95
|
+
ds.RescaleSlope = 1
|
|
96
|
+
ds.RescaleIntercept = 0
|
|
97
|
+
ds.Rows = array.shape[0]
|
|
98
|
+
ds.Columns = array.shape[1]
|
|
99
|
+
|
|
100
|
+
if array.dtype==np.int16:
|
|
101
|
+
ds.BitsAllocated = 16
|
|
102
|
+
ds.BitsStored = 16
|
|
103
|
+
ds.HighBit = 15
|
|
104
|
+
ds.PixelRepresentation = 1 # signed
|
|
105
|
+
ds.PixelData = array.tobytes()
|
|
106
|
+
elif array.dtype==np.float32:
|
|
107
|
+
ds.BitsAllocated = 32
|
|
108
|
+
ds.BitsStored = 32
|
|
109
|
+
ds.HighBit = 31
|
|
110
|
+
ds.PixelRepresentation = 1 # signed
|
|
111
|
+
ds.FloatPixelData = array.tobytes()
|
|
112
|
+
elif array.dtype==np.float64:
|
|
113
|
+
ds.BitsAllocated = 64
|
|
114
|
+
ds.BitsStored = 64
|
|
115
|
+
ds.HighBit = 63
|
|
116
|
+
ds.PixelRepresentation = 1 # signed
|
|
117
|
+
ds.DoubleFloatPixelData = array.tobytes()
|
|
118
|
+
else:
|
|
119
|
+
raise ValueError(
|
|
120
|
+
f"Parametric map storage currently only available for "
|
|
121
|
+
f"32-bit float, 64-bit float or 16-bit int."
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def pixel_data(ds):
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
array = ds.pixel_array
|
|
129
|
+
except:
|
|
130
|
+
raise ValueError("Dataset has no pixel data.")
|
|
131
|
+
|
|
132
|
+
if ds.PixelRepresentation != 1:
|
|
133
|
+
raise ValueError(
|
|
134
|
+
"Currently only signed integer or floating point supported."
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
slope = float(getattr(ds, 'RescaleSlope', 1))
|
|
138
|
+
intercept = float(getattr(ds, 'RescaleIntercept', 0))
|
|
139
|
+
array *= slope
|
|
140
|
+
array += intercept
|
|
141
|
+
if hasattr(ds, 'PixelData'):
|
|
142
|
+
array = array.astype(np.int16)
|
|
143
|
+
elif hasattr(ds, 'FloatPixelData'):
|
|
144
|
+
array = array.astype(np.float32)
|
|
145
|
+
elif hasattr(ds, 'DoubleFloatPixelData'):
|
|
146
|
+
array = array.astype(np.float64)
|
|
147
|
+
return np.transpose(array)
|
|
148
|
+
|
|
65
149
|
|
|
66
|
-
# Add dummy Dimension Organization
|
|
67
|
-
ds.DimensionOrganizationSequence = [Dataset()]
|
|
68
|
-
ds.DimensionOrganizationSequence[0].DimensionOrganizationUID = generate_uid()
|
|
69
150
|
|
|
70
|
-
ds.DimensionIndexSequence = [
|
|
71
|
-
Dataset() for _ in range(1)
|
|
72
|
-
]
|
|
73
|
-
ds.DimensionIndexSequence[0].DimensionOrganizationUID = ds.DimensionOrganizationSequence[0].DimensionOrganizationUID
|
|
74
|
-
ds.DimensionIndexSequence[0].DimensionIndexPointer = (0x0020, 0x9157) # In-stack position
|
|
75
|
-
ds.DimensionIndexSequence[0].FunctionalGroupPointer = (0x0020, 0x9116)
|
|
76
151
|
|
|
77
|
-
return ds
|
|
78
152
|
|
|
79
153
|
|
|
80
154
|
|
dbdicom/utils/image.py
CHANGED
|
@@ -16,9 +16,10 @@ def affine_matrix( # single slice function
|
|
|
16
16
|
column_cosine = np.array(image_orientation[3:])
|
|
17
17
|
slice_cosine = np.cross(row_cosine, column_cosine)
|
|
18
18
|
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
# This should not be addressed here
|
|
20
|
+
# # The coronal orientation has a left-handed reference frame
|
|
21
|
+
# if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
|
|
22
|
+
# slice_cosine = -slice_cosine
|
|
22
23
|
|
|
23
24
|
affine = np.identity(4, dtype=np.float32)
|
|
24
25
|
affine[:3, 0] = row_cosine * column_spacing
|
|
@@ -39,9 +40,9 @@ def slice_location(
|
|
|
39
40
|
column_cosine = np.array(image_orientation[3:])
|
|
40
41
|
slice_cosine = np.cross(row_cosine, column_cosine)
|
|
41
42
|
|
|
42
|
-
# The coronal orientation has a left-handed reference frame
|
|
43
|
-
if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
|
|
44
|
-
|
|
43
|
+
# # The coronal orientation has a left-handed reference frame
|
|
44
|
+
# if np.array_equal(np.around(image_orientation, 3), [1,0,0,0,0,-1]):
|
|
45
|
+
# slice_cosine = -slice_cosine
|
|
45
46
|
|
|
46
47
|
return np.dot(np.array(image_position), slice_cosine)
|
|
47
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbdicom
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: A pythonic interface for reading and writing DICOM databases
|
|
5
5
|
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>, Ebony Gunwhy <e.gunwhy@sheffield.ac.uk>
|
|
6
6
|
Project-URL: Homepage, https://openmiblab.github.io/dbdicom/
|
|
@@ -22,7 +22,5 @@ Requires-Dist: importlib-resources
|
|
|
22
22
|
Requires-Dist: numpy
|
|
23
23
|
Requires-Dist: pandas
|
|
24
24
|
Requires-Dist: vreg
|
|
25
|
-
Requires-Dist: pydicom
|
|
26
|
-
Requires-Dist: python-gdcm
|
|
27
|
-
Requires-Dist: pylibjpeg-libjpeg
|
|
25
|
+
Requires-Dist: pydicom[basic,pixeldata]
|
|
28
26
|
Dynamic: license-file
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
dbdicom/__init__.py,sha256=DyogeTraV6o-FgWdBCbtVEaMmdkMQHkYkraDIE0t8OA,25
|
|
2
|
-
dbdicom/api.py,sha256=
|
|
2
|
+
dbdicom/api.py,sha256=Xcur6TstwvSD8QMDkFn97NDnuVymjCtHWldimG8CDP4,9783
|
|
3
3
|
dbdicom/const.py,sha256=BqBiRRjeiSqDr1W6YvaayD8WKCjG4Cny2NT0GeLM6bI,4269
|
|
4
|
-
dbdicom/
|
|
5
|
-
dbdicom/
|
|
6
|
-
dbdicom/
|
|
4
|
+
dbdicom/database.py,sha256=w835qQHThZsIhoTXlQbZykcKnVrEADgp2mRYBTOKz4g,4627
|
|
5
|
+
dbdicom/dataset.py,sha256=dm0bmBjqb_3uZLYV87gKszlqKMMLrSbaymVROafB5ac,22143
|
|
6
|
+
dbdicom/dbd.py,sha256=xpDiWzlMUmXzYgRCR5jwvvHENbTsq3B89HvK2JxAo3c,26450
|
|
7
|
+
dbdicom/register.py,sha256=5wBQsf4PB6ITHN3clUOMStUy5iYjMnIYUBfhVS2Drio,23692
|
|
7
8
|
dbdicom/external/__init__.py,sha256=XNQqfspyf6vFGedXlRKZsUB8k8E-0W19Uamwn8Aioxo,316
|
|
8
|
-
dbdicom/external/__pycache__/__init__.cpython-311.pyc,sha256=
|
|
9
|
+
dbdicom/external/__pycache__/__init__.cpython-311.pyc,sha256=cIySrImYKo1fJP3-0ZMV-5ZKcZEEDX-uwfZ7I4U-jRs,534
|
|
9
10
|
dbdicom/external/dcm4che/README.md,sha256=0aAGRs36W3_0s5LzWHRGf_tqariS_JP4iJggaxnD4Xw,8987
|
|
10
11
|
dbdicom/external/dcm4che/__init__.py,sha256=YwpeMCLrxffGOkchsGjgAuB6ia3VX_tx9Y7ru9EWtoY,35
|
|
11
|
-
dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc,sha256=
|
|
12
|
+
dbdicom/external/dcm4che/__pycache__/__init__.cpython-311.pyc,sha256=QsnVh0zH1ZSOoNwtTqiirWH8CB0b2eJ0DEvgVoVhZ0Y,248
|
|
12
13
|
dbdicom/external/dcm4che/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
14
|
dbdicom/external/dcm4che/bin/deidentify,sha256=64MNIEpp-CWzFSb6TV0KtyCBvD7XyEsovRjBeyxDqSc,1698
|
|
14
15
|
dbdicom/external/dcm4che/bin/deidentify.bat,sha256=kVXUkcy1C4Y3KjC2NJwmmR0pufSJWmaof_LR5CTAxMg,1455
|
|
15
16
|
dbdicom/external/dcm4che/bin/emf2sf,sha256=svCzkZ-QhdVTV0NNHOpBiwNBMODVWZHJIFA7cWaN2bM,1622
|
|
16
17
|
dbdicom/external/dcm4che/bin/emf2sf.bat,sha256=Vh0ry9KNJX_WXcyCrLSxbJ_6Crot9rjmwi__u2GZqLY,1375
|
|
17
|
-
dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc,sha256=
|
|
18
|
+
dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-311.pyc,sha256=M2mla4vNW1gSUWQps3dx4g8NRd4BaQJLP1OKQHmi6Sk,195
|
|
18
19
|
dbdicom/external/dcm4che/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
20
|
dbdicom/external/dcm4che/etc/emf2sf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
21
|
dbdicom/external/dcm4che/etc/emf2sf/log4j.properties,sha256=3hHcBFt2oNRjvHtix5bfuEsnKfdv5IYOkbsyoY9g7cM,223
|
|
@@ -35,8 +36,8 @@ dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll,sha256=QanyzLy0Cd79-aOV
|
|
|
35
36
|
dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll,sha256=TmjW2SbG4MR3GQ95T8xCVVDLgsdKukgaHBPUvWkfXp8,11039232
|
|
36
37
|
dbdicom/sop_classes/ct_image.py,sha256=16PNv_0e1_7cfxE12JWlx5YQeaTAQVzwtXTjxs3aonk,2812
|
|
37
38
|
dbdicom/sop_classes/enhanced_mr_image.py,sha256=13j4EGXniBpJxpzzL3Xa4y3g5OKhMd5Ct7cjPGOYQY4,35496
|
|
38
|
-
dbdicom/sop_classes/mr_image.py,sha256=
|
|
39
|
-
dbdicom/sop_classes/parametric_map.py,sha256=
|
|
39
|
+
dbdicom/sop_classes/mr_image.py,sha256=nHSQIh_zpdmZ0VhwKCVr9iqkluHxl1ASQ75Fr9OeNXI,10270
|
|
40
|
+
dbdicom/sop_classes/parametric_map.py,sha256=2OKBuC2bo03OEpKqimQS-nVGFp1cKRPYwVgmDGVf1JU,12288
|
|
40
41
|
dbdicom/sop_classes/secondary_capture.py,sha256=wgNRX8qyhV7HR7Jq2tQWPPuGpiRzYl6qPOgK6qFbPUc,4541
|
|
41
42
|
dbdicom/sop_classes/segmentation.py,sha256=I8-PciIoIz27_-dZ4esBZSw0TBBbO8KbNYTiTmVe62g,11465
|
|
42
43
|
dbdicom/sop_classes/ultrasound_multiframe_image.py,sha256=j3KN5R90j6WwPMy01hAN2_XSum5TvksF2MYoNGfX_yE,2797
|
|
@@ -44,10 +45,10 @@ dbdicom/sop_classes/xray_angiographic_image.py,sha256=nWysCGaEWKVNItnOgyJfcGMpS3
|
|
|
44
45
|
dbdicom/utils/arrays.py,sha256=wiqCczLXlNl0qIePVOwCYvbAJhPveNorplkhtGleS48,1121
|
|
45
46
|
dbdicom/utils/dcm4che.py,sha256=Vxq8NYWWK3BuqJkzhBQ89oMqzJlnxqTxgsgTo_Frznc,2317
|
|
46
47
|
dbdicom/utils/files.py,sha256=qhWNJqeWnRjDNbERpC6Mz962_TW9mFdvd2lnBbK3xt4,2259
|
|
47
|
-
dbdicom/utils/image.py,sha256=
|
|
48
|
+
dbdicom/utils/image.py,sha256=dCjukz9Zvpl4cP3KR1Y4hmKkox5KaFiEhdxDWDEdNec,4110
|
|
48
49
|
dbdicom/utils/variables.py,sha256=vUh5cDnmCft5hoXDYXUvfkg5Cy5WlgMAogU38Y_BKRo,5753
|
|
49
|
-
dbdicom-0.3.
|
|
50
|
-
dbdicom-0.3.
|
|
51
|
-
dbdicom-0.3.
|
|
52
|
-
dbdicom-0.3.
|
|
53
|
-
dbdicom-0.3.
|
|
50
|
+
dbdicom-0.3.2.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
51
|
+
dbdicom-0.3.2.dist-info/METADATA,sha256=zqs5ghuuW4o1UR_QkGhiM9afOqmKYWMg0d54ThWRV0k,1030
|
|
52
|
+
dbdicom-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
53
|
+
dbdicom-0.3.2.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
|
|
54
|
+
dbdicom-0.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|