dbdicom 0.2.1__py3-none-any.whl → 0.2.4__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 +31 -4
- dbdicom/ds/types/mr_image.py +18 -7
- dbdicom/extensions/__init__.py +9 -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 +54 -19
- dbdicom/types/series.py +2183 -412
- dbdicom/utils/image.py +256 -48
- dbdicom-0.2.4.dist-info/METADATA +89 -0
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.4.dist-info}/RECORD +26 -41
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.4.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/utils/vreg.py +0 -2626
- 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.4.dist-info}/LICENSE +0 -0
- {dbdicom-0.2.1.dist-info → dbdicom-0.2.4.dist-info}/top_level.txt +0 -0
dbdicom/utils/image.py
CHANGED
|
@@ -1,8 +1,94 @@
|
|
|
1
|
+
import math
|
|
1
2
|
import numpy as np
|
|
2
3
|
from scipy.interpolate import interpn
|
|
3
4
|
from scipy.ndimage import affine_transform
|
|
4
5
|
|
|
5
6
|
|
|
7
|
+
def as_mosaic(array, rows=None):
|
|
8
|
+
"""Reformat a 3D array (x,y,z) into a 2D mosaic"""
|
|
9
|
+
|
|
10
|
+
nz = array.shape[2]
|
|
11
|
+
if rows is None:
|
|
12
|
+
rows = math.ceil(math.sqrt(nz))
|
|
13
|
+
cols = math.ceil(nz/rows)
|
|
14
|
+
mosaic = np.zeros((array.shape[0]*cols, array.shape[1]*rows))
|
|
15
|
+
for k in range(nz):
|
|
16
|
+
j = math.floor(k/cols)
|
|
17
|
+
i = k-j*cols
|
|
18
|
+
mosaic[
|
|
19
|
+
i*array.shape[0]:(i+1)*array.shape[0],
|
|
20
|
+
j*array.shape[1]:(j+1)*array.shape[1],
|
|
21
|
+
] = array[:,:,k]
|
|
22
|
+
return mosaic
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def ellipsoid(a, b, c, spacing=(1., 1., 1.), levelset=False):
|
|
28
|
+
"""
|
|
29
|
+
Generates ellipsoid with semimajor axes aligned with grid dimensions
|
|
30
|
+
on grid with specified `spacing`.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
a : float
|
|
35
|
+
Length of semimajor axis aligned with x-axis.
|
|
36
|
+
b : float
|
|
37
|
+
Length of semimajor axis aligned with y-axis.
|
|
38
|
+
c : float
|
|
39
|
+
Length of semimajor axis aligned with z-axis.
|
|
40
|
+
spacing : tuple of floats, length 3
|
|
41
|
+
Spacing in (x, y, z) spatial dimensions.
|
|
42
|
+
levelset : bool
|
|
43
|
+
If True, returns the level set for this ellipsoid (signed level
|
|
44
|
+
set about zero, with positive denoting interior) as np.float64.
|
|
45
|
+
False returns a binarized version of said level set.
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
ellip : (N, M, P) array
|
|
50
|
+
Ellipsoid centered in a correctly sized array for given `spacing`.
|
|
51
|
+
Boolean dtype unless `levelset=True`, in which case a float array is
|
|
52
|
+
returned with the level set above 0.0 representing the ellipsoid.
|
|
53
|
+
|
|
54
|
+
Note
|
|
55
|
+
----
|
|
56
|
+
This function is copy-pasted directly from skimage source code without modification - this to avoid bringing in skimage as an essential dependency.
|
|
57
|
+
|
|
58
|
+
"""
|
|
59
|
+
if (a <= 0) or (b <= 0) or (c <= 0):
|
|
60
|
+
raise ValueError('Parameters a, b, and c must all be > 0')
|
|
61
|
+
|
|
62
|
+
offset = np.r_[1, 1, 1] * np.r_[spacing]
|
|
63
|
+
|
|
64
|
+
# Calculate limits, and ensure output volume is odd & symmetric
|
|
65
|
+
low = np.ceil(- np.r_[a, b, c] - offset)
|
|
66
|
+
high = np.floor(np.r_[a, b, c] + offset + 1)
|
|
67
|
+
|
|
68
|
+
for dim in range(3):
|
|
69
|
+
if (high[dim] - low[dim]) % 2 == 0:
|
|
70
|
+
low[dim] -= 1
|
|
71
|
+
num = np.arange(low[dim], high[dim], spacing[dim])
|
|
72
|
+
if 0 not in num:
|
|
73
|
+
low[dim] -= np.max(num[num < 0])
|
|
74
|
+
|
|
75
|
+
# Generate (anisotropic) spatial grid
|
|
76
|
+
x, y, z = np.mgrid[low[0]:high[0]:spacing[0],
|
|
77
|
+
low[1]:high[1]:spacing[1],
|
|
78
|
+
low[2]:high[2]:spacing[2]]
|
|
79
|
+
|
|
80
|
+
if not levelset:
|
|
81
|
+
arr = ((x / float(a)) ** 2 +
|
|
82
|
+
(y / float(b)) ** 2 +
|
|
83
|
+
(z / float(c)) ** 2) <= 1
|
|
84
|
+
else:
|
|
85
|
+
arr = ((x / float(a)) ** 2 +
|
|
86
|
+
(y / float(b)) ** 2 +
|
|
87
|
+
(z / float(c)) ** 2) - 1
|
|
88
|
+
|
|
89
|
+
return arr
|
|
90
|
+
|
|
91
|
+
|
|
6
92
|
def multislice_affine_transform(array_source, affine_source, output_affine, slice_thickness=None, **kwargs):
|
|
7
93
|
"""Generalization of scipy's affine transform.
|
|
8
94
|
|
|
@@ -330,29 +416,7 @@ def affine_matrix( # single slice function
|
|
|
330
416
|
image_orientation, # ImageOrientationPatient
|
|
331
417
|
image_position, # ImagePositionPatient
|
|
332
418
|
pixel_spacing, # PixelSpacing
|
|
333
|
-
|
|
334
|
-
"""
|
|
335
|
-
Calculate an affine transformation matrix for a single slice of an image in the DICOM file format.
|
|
336
|
-
The affine transformation matrix can be used to transform the image from its original coordinates
|
|
337
|
-
to a new set of coordinates.
|
|
338
|
-
|
|
339
|
-
Parameters:
|
|
340
|
-
image_orientation (list): a list of 6 elements representing the ImageOrientationPatient
|
|
341
|
-
DICOM tag for the image. This specifies the orientation of the
|
|
342
|
-
image slices in 3D space.
|
|
343
|
-
image_position (list): a list of 3 elements representing the ImagePositionPatient DICOM
|
|
344
|
-
tag for the slice. This specifies the position of the slice in 3D space.
|
|
345
|
-
pixel_spacing (list): a list of 2 elements representing the PixelSpacing DICOM tag for the
|
|
346
|
-
image. This specifies the spacing between pixels in the rows and columns
|
|
347
|
-
of each slice.
|
|
348
|
-
slice_spacing (float): a float representing the SpacingBetweenSlices DICOM tag for the image. This
|
|
349
|
-
specifies the spacing between slices in the image.
|
|
350
|
-
|
|
351
|
-
Returns:
|
|
352
|
-
np.ndarray: an affine transformation matrix represented as a 4x4 NumPy array with dtype `float32`.
|
|
353
|
-
The matrix can be used to transform the image from its original coordinates to a new set
|
|
354
|
-
of coordinates.
|
|
355
|
-
"""
|
|
419
|
+
slice_thickness): # SliceThickness
|
|
356
420
|
|
|
357
421
|
row_spacing = pixel_spacing[0]
|
|
358
422
|
column_spacing = pixel_spacing[1]
|
|
@@ -364,16 +428,16 @@ def affine_matrix( # single slice function
|
|
|
364
428
|
affine = np.identity(4, dtype=np.float32)
|
|
365
429
|
affine[:3, 0] = row_cosine * column_spacing
|
|
366
430
|
affine[:3, 1] = column_cosine * row_spacing
|
|
367
|
-
affine[:3, 2] = slice_cosine *
|
|
431
|
+
affine[:3, 2] = slice_cosine * slice_thickness
|
|
368
432
|
affine[:3, 3] = image_position
|
|
369
433
|
|
|
370
434
|
return affine
|
|
371
435
|
|
|
372
436
|
|
|
373
|
-
def slice_location(
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
):
|
|
437
|
+
def slice_location(
|
|
438
|
+
image_orientation:list, # ImageOrientationPatient
|
|
439
|
+
image_position:list, # ImagePositionPatient
|
|
440
|
+
) -> float:
|
|
377
441
|
"""Calculate Slice Location"""
|
|
378
442
|
|
|
379
443
|
row_cosine = np.array(image_orientation[:3])
|
|
@@ -383,6 +447,27 @@ def slice_location(
|
|
|
383
447
|
return np.dot(np.array(image_position), slice_cosine)
|
|
384
448
|
|
|
385
449
|
|
|
450
|
+
def image_position_from_slice_location(slice_location:float, affine=np.eye(4))->list:
|
|
451
|
+
v = dismantle_affine_matrix(affine)
|
|
452
|
+
return list(affine[:3, 3] + slice_location * np.array(v['slice_cosine']))
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def image_position_patient(affine, number_of_slices):
|
|
456
|
+
slab = dismantle_affine_matrix(affine)
|
|
457
|
+
image_positions = []
|
|
458
|
+
image_locations = []
|
|
459
|
+
for s in range(number_of_slices):
|
|
460
|
+
pos = [
|
|
461
|
+
slab['ImagePositionPatient'][i]
|
|
462
|
+
+ s*slab['SpacingBetweenSlices']*slab['slice_cosine'][i]
|
|
463
|
+
for i in range(3)
|
|
464
|
+
]
|
|
465
|
+
loc = np.dot(np.array(pos), np.array(slab['slice_cosine']))
|
|
466
|
+
image_positions.append(pos)
|
|
467
|
+
image_locations.append(loc)
|
|
468
|
+
return image_positions, image_locations
|
|
469
|
+
|
|
470
|
+
|
|
386
471
|
def affine_matrix_multislice(
|
|
387
472
|
image_orientation, # ImageOrientationPatient (assume same for all slices)
|
|
388
473
|
image_positions, # ImagePositionPatient for all slices
|
|
@@ -423,17 +508,116 @@ def dismantle_affine_matrix(affine):
|
|
|
423
508
|
# ImagePositionPatient_i = ImagePositionPatient + i * SpacingBetweenSlices * slice_cosine
|
|
424
509
|
column_spacing = np.linalg.norm(affine[:3, 0])
|
|
425
510
|
row_spacing = np.linalg.norm(affine[:3, 1])
|
|
426
|
-
|
|
511
|
+
slice_thickness = np.linalg.norm(affine[:3, 2])
|
|
427
512
|
row_cosine = affine[:3, 0] / column_spacing
|
|
428
513
|
column_cosine = affine[:3, 1] / row_spacing
|
|
429
|
-
slice_cosine = affine[:3, 2] /
|
|
514
|
+
slice_cosine = affine[:3, 2] / slice_thickness
|
|
430
515
|
return {
|
|
431
516
|
'PixelSpacing': [row_spacing, column_spacing],
|
|
432
|
-
'SpacingBetweenSlices':
|
|
517
|
+
'SpacingBetweenSlices': slice_thickness, # Obsolete
|
|
518
|
+
'SliceThickness': slice_thickness,
|
|
433
519
|
'ImageOrientationPatient': row_cosine.tolist() + column_cosine.tolist(),
|
|
434
520
|
'ImagePositionPatient': affine[:3, 3].tolist(), # first slice for a volume
|
|
435
521
|
'slice_cosine': slice_cosine.tolist()}
|
|
436
522
|
|
|
523
|
+
|
|
524
|
+
def unstack_affine(affine, nz):
|
|
525
|
+
|
|
526
|
+
pos0 = affine[:3, 3]
|
|
527
|
+
slice_vec = affine[:3, 2]
|
|
528
|
+
|
|
529
|
+
affines = []
|
|
530
|
+
for z in range(nz):
|
|
531
|
+
affine_z = affine.copy()
|
|
532
|
+
affine_z[:3, 3] = pos0 + z*slice_vec
|
|
533
|
+
affines.append(affine_z)
|
|
534
|
+
|
|
535
|
+
return affines
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def stack_affines(affines):
|
|
539
|
+
|
|
540
|
+
aff = [dismantle_affine_matrix(a) for a in affines]
|
|
541
|
+
|
|
542
|
+
# Check that all affines have the same orientation
|
|
543
|
+
orient = [a['ImageOrientationPatient'] for a in aff]
|
|
544
|
+
orient = [x for i, x in enumerate(orient) if i==orient.index(x)]
|
|
545
|
+
if len(orient) > 1:
|
|
546
|
+
raise ValueError(
|
|
547
|
+
"Slices have different orientations and cannot be stacked")
|
|
548
|
+
orient = orient[0]
|
|
549
|
+
|
|
550
|
+
# Check that all affines have the same slice_cosine
|
|
551
|
+
slice_cosine = [a['slice_cosine'] for a in aff]
|
|
552
|
+
slice_cosine = [x for i, x in enumerate(slice_cosine) if i==slice_cosine.index(x)]
|
|
553
|
+
if len(slice_cosine) > 1:
|
|
554
|
+
raise ValueError(
|
|
555
|
+
"Slices have different slice cosines and cannot be stacked")
|
|
556
|
+
slice_cosine = slice_cosine[0]
|
|
557
|
+
|
|
558
|
+
# Check all slices have the same thickness
|
|
559
|
+
thick = [a['SpacingBetweenSlices'] for a in aff] # note incorrectly named
|
|
560
|
+
thick = np.unique(thick)
|
|
561
|
+
if len(thick)>1:
|
|
562
|
+
raise ValueError(
|
|
563
|
+
"Slices have different slice thickness and cannot be stacked")
|
|
564
|
+
thick = thick[0]
|
|
565
|
+
|
|
566
|
+
# Check all slices have the same pixel spacing
|
|
567
|
+
pix_space = [a['PixelSpacing'] for a in aff]
|
|
568
|
+
pix_space = [x for i, x in enumerate(pix_space) if i==pix_space.index(x)]
|
|
569
|
+
if len(pix_space)>1:
|
|
570
|
+
raise ValueError(
|
|
571
|
+
"Slices have different pixel sizes and cannot be stacked. ")
|
|
572
|
+
pix_space = pix_space[0]
|
|
573
|
+
|
|
574
|
+
# Get orientations (orthogonal assumed here)
|
|
575
|
+
row_vec = np.array(orient[:3])
|
|
576
|
+
column_vec = np.array(orient[3:])
|
|
577
|
+
slice_vec = np.array(slice_cosine)
|
|
578
|
+
|
|
579
|
+
# Check that all slice spacings are equal
|
|
580
|
+
pos = [a['ImagePositionPatient'] for a in aff]
|
|
581
|
+
loc = np.array([np.dot(p, slice_vec) for p in pos])
|
|
582
|
+
# Get unique slice spacing (to micrometer precision)
|
|
583
|
+
slice_spacing = np.unique(np.around(loc[1:]-loc[:-1], 3))
|
|
584
|
+
# If there is more than 1 slice spacing, the series is multislice
|
|
585
|
+
if slice_spacing.size != 1:
|
|
586
|
+
raise ValueError(
|
|
587
|
+
"There are different spacings between consecutive slices. "
|
|
588
|
+
"The slices cannot be stacked.")
|
|
589
|
+
slice_spacing = slice_spacing[0]
|
|
590
|
+
|
|
591
|
+
# Check the slice spacing is equal to the slice thickness
|
|
592
|
+
if np.around(thick-slice_spacing, 3) != 0:
|
|
593
|
+
raise ValueError(
|
|
594
|
+
"This is a multi-slice sequence, i.e. the slice spacing is "
|
|
595
|
+
"different from the slice thickness. If you want to stack the "
|
|
596
|
+
"slices, set the slice thickness equal to the slice spacing "
|
|
597
|
+
"first (" + str(slice_spacing) + " mm).")
|
|
598
|
+
|
|
599
|
+
# Check that all positions are on the slice vector
|
|
600
|
+
for p in pos[1:]:
|
|
601
|
+
# Position relative to first slice position
|
|
602
|
+
prel = np.array(p)-np.array(pos[0])
|
|
603
|
+
# Parallel means cross product has length zero
|
|
604
|
+
norm = np.linalg.norm(np.cross(slice_vec, prel))
|
|
605
|
+
# Round to micrometers to avoid numerical error
|
|
606
|
+
if np.round(norm, 3) != 0:
|
|
607
|
+
raise ValueError(
|
|
608
|
+
"Slices are not aligned and cannot be stacked")
|
|
609
|
+
|
|
610
|
+
# Build affine for the stack
|
|
611
|
+
affine = np.identity(4, dtype=np.float32)
|
|
612
|
+
affine[:3, 0] = row_vec * pix_space[1]
|
|
613
|
+
affine[:3, 1] = column_vec * pix_space[0]
|
|
614
|
+
affine[:3, 2] = slice_vec * slice_spacing
|
|
615
|
+
affine[:3, 3] = pos[0]
|
|
616
|
+
|
|
617
|
+
return affine
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
437
621
|
def affine_to_RAH(affine):
|
|
438
622
|
"""Convert to the coordinate system used in NifTi"""
|
|
439
623
|
|
|
@@ -442,22 +626,6 @@ def affine_to_RAH(affine):
|
|
|
442
626
|
return np.matmul(rot_180, affine)
|
|
443
627
|
|
|
444
628
|
|
|
445
|
-
def image_position_patient(affine, number_of_slices):
|
|
446
|
-
slab = dismantle_affine_matrix(affine)
|
|
447
|
-
image_positions = []
|
|
448
|
-
image_locations = []
|
|
449
|
-
for s in range(number_of_slices):
|
|
450
|
-
pos = [
|
|
451
|
-
slab['ImagePositionPatient'][i]
|
|
452
|
-
+ s*slab['SpacingBetweenSlices']*slab['slice_cosine'][i]
|
|
453
|
-
for i in range(3)
|
|
454
|
-
]
|
|
455
|
-
loc = np.dot(np.array(pos), np.array(slab['slice_cosine']))
|
|
456
|
-
image_positions.append(pos)
|
|
457
|
-
image_locations.append(loc)
|
|
458
|
-
return image_positions, image_locations
|
|
459
|
-
|
|
460
|
-
|
|
461
629
|
def clip(array, value_range = None):
|
|
462
630
|
|
|
463
631
|
array[np.isnan(array)] = 0
|
|
@@ -467,7 +635,47 @@ def clip(array, value_range = None):
|
|
|
467
635
|
return np.clip(array, value_range[0], value_range[1])
|
|
468
636
|
|
|
469
637
|
|
|
470
|
-
def scale_to_range(array, bits_allocated):
|
|
638
|
+
def scale_to_range(array, bits_allocated, signed=False):
|
|
639
|
+
|
|
640
|
+
range = 2.0**bits_allocated - 1
|
|
641
|
+
if signed:
|
|
642
|
+
minval = -2.0**(bits_allocated-1)
|
|
643
|
+
else:
|
|
644
|
+
minval = 0
|
|
645
|
+
maximum = np.amax(array)
|
|
646
|
+
minimum = np.amin(array)
|
|
647
|
+
if maximum == minimum:
|
|
648
|
+
slope = 1
|
|
649
|
+
else:
|
|
650
|
+
slope = range / (maximum - minimum)
|
|
651
|
+
intercept = -slope * minimum + minval
|
|
652
|
+
array *= slope
|
|
653
|
+
array += intercept
|
|
654
|
+
|
|
655
|
+
if bits_allocated == 8:
|
|
656
|
+
if signed:
|
|
657
|
+
return array.astype(np.int8), slope, intercept
|
|
658
|
+
else:
|
|
659
|
+
return array.astype(np.uint8), slope, intercept
|
|
660
|
+
if bits_allocated == 16:
|
|
661
|
+
if signed:
|
|
662
|
+
return array.astype(np.int16), slope, intercept
|
|
663
|
+
else:
|
|
664
|
+
return array.astype(np.uint16), slope, intercept
|
|
665
|
+
if bits_allocated == 32:
|
|
666
|
+
if signed:
|
|
667
|
+
return array.astype(np.int32), slope, intercept
|
|
668
|
+
else:
|
|
669
|
+
return array.astype(np.uint32), slope, intercept
|
|
670
|
+
if bits_allocated == 64:
|
|
671
|
+
if signed:
|
|
672
|
+
return array.astype(np.int64), slope, intercept
|
|
673
|
+
else:
|
|
674
|
+
return array.astype(np.uint64), slope, intercept
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
def _scale_to_range(array, bits_allocated):
|
|
678
|
+
# Obsolete - generalized as above
|
|
471
679
|
|
|
472
680
|
range = 2.0**bits_allocated - 1
|
|
473
681
|
maximum = np.amax(array)
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: dbdicom
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: A pythonic interface for reading and writing DICOM databases
|
|
5
|
+
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>, Ebony Gunwhy <e.gunwhy@sheffield.ac.uk>
|
|
6
|
+
Project-URL: Homepage, https://qib-sheffield.github.io/dbdicom/
|
|
7
|
+
Keywords: python,medical imaging,DICOM
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Requires-Python: >=3.6
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: matplotlib
|
|
21
|
+
Requires-Dist: nibabel
|
|
22
|
+
Requires-Dist: numpy<=1.26.4
|
|
23
|
+
Requires-Dist: pandas
|
|
24
|
+
Requires-Dist: pydicom
|
|
25
|
+
Requires-Dist: python-gdcm
|
|
26
|
+
Requires-Dist: pylibjpeg-libjpeg
|
|
27
|
+
Requires-Dist: importlib-resources
|
|
28
|
+
Requires-Dist: scipy
|
|
29
|
+
Requires-Dist: imageio
|
|
30
|
+
Requires-Dist: vreg
|
|
31
|
+
Provides-Extra: docs
|
|
32
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
33
|
+
Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
34
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
36
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
|
37
|
+
Requires-Dist: sphinx-remove-toctrees; extra == "docs"
|
|
38
|
+
Requires-Dist: autodocsumm; extra == "docs"
|
|
39
|
+
Requires-Dist: docutils; extra == "docs"
|
|
40
|
+
Requires-Dist: sphinxcontrib-applehelp; extra == "docs"
|
|
41
|
+
Requires-Dist: sphinxcontrib-devhelp; extra == "docs"
|
|
42
|
+
Requires-Dist: sphinxcontrib-htmlhelp; extra == "docs"
|
|
43
|
+
Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
|
|
44
|
+
Requires-Dist: sphinxcontrib-qthelp; extra == "docs"
|
|
45
|
+
Requires-Dist: sphinxcontrib-serializinghtml; extra == "docs"
|
|
46
|
+
Requires-Dist: sphinx-gallery; extra == "docs"
|
|
47
|
+
Provides-Extra: extensions
|
|
48
|
+
Requires-Dist: scipy; extra == "extensions"
|
|
49
|
+
Requires-Dist: scikit-image<=0.19.0; extra == "extensions"
|
|
50
|
+
Requires-Dist: SimpleITK-SimpleElastix; extra == "extensions"
|
|
51
|
+
Requires-Dist: itk-elastix; extra == "extensions"
|
|
52
|
+
Requires-Dist: dipy; extra == "extensions"
|
|
53
|
+
Requires-Dist: scikit-learn; extra == "extensions"
|
|
54
|
+
|
|
55
|
+
`dbdicom` is a Pythonic interface for reading and writing DICOM databases.
|
|
56
|
+
|
|
57
|
+
# Installation
|
|
58
|
+
|
|
59
|
+
`pip install dbdicom`
|
|
60
|
+
|
|
61
|
+
# Documentation
|
|
62
|
+
|
|
63
|
+
For more detail, see the current [dbdicom documentation](https://qib-sheffield.github.io/dbdicom/).
|
|
64
|
+
|
|
65
|
+
# Ambition
|
|
66
|
+
|
|
67
|
+
The DICOM format is the universally recognised standard for medical imaging,
|
|
68
|
+
but working with DICOM data remains a challenging task for data scientists.
|
|
69
|
+
|
|
70
|
+
``dbdicom`` aims to provide an intuitive programming interface for reading and
|
|
71
|
+
writing DICOM databases - replacing unfamiliar DICOM-native concepts by
|
|
72
|
+
pythonic language and syntax.
|
|
73
|
+
|
|
74
|
+
# Disclaimer
|
|
75
|
+
|
|
76
|
+
`dbdicom` is developed in public and currently trialled in ongoing
|
|
77
|
+
multi-centre clinical studies
|
|
78
|
+
[iBEAt](https://bmcnephrol.biomedcentral.com/articles/10.1186/s12882-020-01901-x>)
|
|
79
|
+
and [AFiRM](https://www.uhdb.nhs.uk/afirm-study/). However, ``dbdicom`` is
|
|
80
|
+
work in progress and **not yet sufficiently stable for wider use**. Current
|
|
81
|
+
dissemination activities, such as on the
|
|
82
|
+
[ISMRM (Toronto 2023)](https://www.ismrm.org/23m/), are limited in scope and
|
|
83
|
+
intended to get early feedback from the community.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
@@ -1,32 +1,37 @@
|
|
|
1
|
-
dbdicom/__init__.py,sha256=
|
|
2
|
-
dbdicom/create.py,sha256=
|
|
3
|
-
dbdicom/
|
|
1
|
+
dbdicom/__init__.py,sha256=rXC7OyQufyuAHqkUxxnw-LaQSw_Z1pZu86QNvj5wtrI,503
|
|
2
|
+
dbdicom/create.py,sha256=v_hLU-5OtJn38FSUDw7d6B0bCIg1LQB49449aG6Jrhs,16518
|
|
3
|
+
dbdicom/dro.py,sha256=onVacXzCqFj6MdKOAAIB8jE-AVcrdbrJHE60sihAuzY,8138
|
|
4
|
+
dbdicom/manager.py,sha256=dn09ieznzTThhvcSBsLLwW5kAS6iWRTau-fhSlXyWhQ,83685
|
|
4
5
|
dbdicom/message.py,sha256=kHcb-WuK_SzIqX76X55YIqSbTn3OdFC052qDkaKfIC8,3581
|
|
5
|
-
dbdicom/
|
|
6
|
+
dbdicom/pipelines.py,sha256=keBsBEjEipfu9reh3ExhHT2sgRksbL5MuRDHF4OywEI,2280
|
|
7
|
+
dbdicom/record.py,sha256=p5WH1f5Bearn5ZHdCT9h11BUfo5O9GuSz1Dk8gH4BLM,66387
|
|
6
8
|
dbdicom/ds/__init__.py,sha256=gX_ui37gPc_A9h0ZsBYj1-Uh7QdlmtBGrbcbXuOM8Bk,459
|
|
7
9
|
dbdicom/ds/create.py,sha256=_np1bXXH6lfls6JSrPPbgy8X8q6QOj5s83tYUIAaEUk,2132
|
|
8
|
-
dbdicom/ds/dataset.py,sha256=
|
|
10
|
+
dbdicom/ds/dataset.py,sha256=T4SeXSz6aPgK9T7kmk8IN1hvuKfSQ-E-_CrhcXKaQ4E,29347
|
|
9
11
|
dbdicom/ds/dictionaries.py,sha256=g_9EB5jXBmzxp0GFhYC6lQ-tKwxje03ukV5EAH3E_l0,23717
|
|
10
12
|
dbdicom/ds/types/ct_image.py,sha256=2TvEl267TnIkkuJQzPLh9STeSJxKt_ZQi4SEBYmQuiI,3189
|
|
11
13
|
dbdicom/ds/types/enhanced_mr_image.py,sha256=lTvLhMpCiDauAov_IW5epCFKKRhgLfy2d0oC2uab0wc,31336
|
|
12
|
-
dbdicom/ds/types/mr_image.py,sha256=
|
|
14
|
+
dbdicom/ds/types/mr_image.py,sha256=Eaz_jma1VQ2sh0RBWUnQX-8AgPst859e9LFhvv9Rnzw,9769
|
|
13
15
|
dbdicom/ds/types/parametric_map.py,sha256=hc5ms5SarLu3ocitK4aM4dW38rbUxDWVRExFeFmZsVY,11699
|
|
14
16
|
dbdicom/ds/types/ultrasound_multiframe_image.py,sha256=9x2G4pRFYXSoxnaAMLF8okusSkWsSzCdGr5jltxD0Wc,3213
|
|
15
17
|
dbdicom/ds/types/xray_angiographic_image.py,sha256=KhDDVVsZ3himE1P6qFdi401rYcbWCyGZx7inqg-v8oc,3676
|
|
18
|
+
dbdicom/extensions/__init__.py,sha256=ag6Qs2g3g9VHYF1WKsGxMpv_HgbqjfPn_UzjoEaKG-0,115
|
|
19
|
+
dbdicom/extensions/dipy.py,sha256=CrSjU14JwNpMP7AIH-CR3wkoQB19MYbS4efOEVczurQ,16806
|
|
20
|
+
dbdicom/extensions/elastix.py,sha256=0gNgiC0RAEjLBhovgRtaLy31xxUy6rJWoapm_3tMCQ8,22522
|
|
21
|
+
dbdicom/extensions/matplotlib.py,sha256=k9KK-mZW8TpW37PgoFre3yb4ffRCRrPVeQKEGZnQoXw,4218
|
|
22
|
+
dbdicom/extensions/numpy.py,sha256=13PPKj-GCAstSb7uQ8_XAZ2borYkDVKhqcAs7KVA6pc,10542
|
|
23
|
+
dbdicom/extensions/scipy.py,sha256=xQ3H3puoE9kF1qG5Pvl6gaQD4TdL6-f3V8Cz7z1_L0A,52884
|
|
24
|
+
dbdicom/extensions/skimage.py,sha256=hP2get4UTpu0ZSlbAvQmwaKRvGupHLn39L0BctgzZ-0,38563
|
|
25
|
+
dbdicom/extensions/sklearn.py,sha256=KxxAlzh8ZI7YBkLS529k9VaAObCCVZT8exvEQThcYCY,9351
|
|
26
|
+
dbdicom/extensions/vreg.py,sha256=PbCqTRsLKmbksRYsM_piBrcJL2XV89_jenw85Ozjzwk,67522
|
|
16
27
|
dbdicom/external/__init__.py,sha256=XNQqfspyf6vFGedXlRKZsUB8k8E-0W19Uamwn8Aioxo,316
|
|
17
|
-
dbdicom/external/__pycache__/__init__.cpython-310.pyc,sha256=LKtgv6wDok4_xp5IURsNH7S3SQgztzQnqzLCLTKcuf4,512
|
|
18
|
-
dbdicom/external/__pycache__/__init__.cpython-37.pyc,sha256=SjfoDOtOd25W3k1Y8zaeBSY2abdP9dq4O55wJb2E9F8,506
|
|
19
28
|
dbdicom/external/dcm4che/README.md,sha256=0aAGRs36W3_0s5LzWHRGf_tqariS_JP4iJggaxnD4Xw,8987
|
|
20
29
|
dbdicom/external/dcm4che/__init__.py,sha256=YwpeMCLrxffGOkchsGjgAuB6ia3VX_tx9Y7ru9EWtoY,35
|
|
21
|
-
dbdicom/external/dcm4che/__pycache__/__init__.cpython-310.pyc,sha256=OjXp4gwnAgd533yoQ3JzLFutR2XrWe1esPJUbyT4bP0,236
|
|
22
|
-
dbdicom/external/dcm4che/__pycache__/__init__.cpython-37.pyc,sha256=qxy0fJnxAEcx5vq3DGFoIlCYVpuPWfPdFMaKXtIzUdI,230
|
|
23
30
|
dbdicom/external/dcm4che/bin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
31
|
dbdicom/external/dcm4che/bin/deidentify,sha256=64MNIEpp-CWzFSb6TV0KtyCBvD7XyEsovRjBeyxDqSc,1698
|
|
25
32
|
dbdicom/external/dcm4che/bin/deidentify.bat,sha256=kVXUkcy1C4Y3KjC2NJwmmR0pufSJWmaof_LR5CTAxMg,1455
|
|
26
|
-
dbdicom/external/dcm4che/bin/emf2sf,sha256=
|
|
33
|
+
dbdicom/external/dcm4che/bin/emf2sf,sha256=svCzkZ-QhdVTV0NNHOpBiwNBMODVWZHJIFA7cWaN2bM,1622
|
|
27
34
|
dbdicom/external/dcm4che/bin/emf2sf.bat,sha256=Vh0ry9KNJX_WXcyCrLSxbJ_6Crot9rjmwi__u2GZqLY,1375
|
|
28
|
-
dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-310.pyc,sha256=_jhZPzvLDVI9KAjeAn8oIYVIIXRgBxIMB_qJT-LIk0k,191
|
|
29
|
-
dbdicom/external/dcm4che/bin/__pycache__/__init__.cpython-37.pyc,sha256=34NVXTsQEUo91tRZKWuG49EJiYpv5lxlORumlJSXJ8Q,185
|
|
30
35
|
dbdicom/external/dcm4che/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
36
|
dbdicom/external/dcm4che/etc/emf2sf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
37
|
dbdicom/external/dcm4che/etc/emf2sf/log4j.properties,sha256=3hHcBFt2oNRjvHtix5bfuEsnKfdv5IYOkbsyoY9g7cM,223
|
|
@@ -39,43 +44,23 @@ dbdicom/external/dcm4che/lib/dcm4che-tool-emf2sf-5.23.1.jar,sha256=pkpJRD00HQ4sE
|
|
|
39
44
|
dbdicom/external/dcm4che/lib/log4j-1.2.17.jar,sha256=HTFpZEVpdyBScJF1Q2kIKmZRvUl4G2AF3rlOVnU0Bvk,489884
|
|
40
45
|
dbdicom/external/dcm4che/lib/slf4j-api-1.7.30.jar,sha256=zboHlk0btAoHYUhcax6ML4_Z6x0ZxTkorA1_lRAQXFc,41472
|
|
41
46
|
dbdicom/external/dcm4che/lib/slf4j-log4j12-1.7.30.jar,sha256=TUHgHEDK-KbHSt0rBzBV2KTOHDDlgVQXexPxLXirvns,12211
|
|
42
|
-
dbdicom/external/dcm4che/lib/linux-x86/libclib_jiio.so,sha256=NaRXHsqHTT_qv3epFw0AY5gx3xmjllszGz5cyw7FmzM,1244729
|
|
43
|
-
dbdicom/external/dcm4che/lib/linux-x86-64/libclib_jiio.so,sha256=qzeCyA8jHAvJeihlUNzv9uJn-5ZGBFdkbknjdXB67dU,1368348
|
|
44
|
-
dbdicom/external/dcm4che/lib/linux-x86-64/libopencv_java.so,sha256=miN3S6aaRDOHEYYyjUHz_4N4E0StenKoKXOdEF7fFXk,19261440
|
|
45
47
|
dbdicom/external/dcm4che/lib/macosx-x86-64/libopencv_java.jnilib,sha256=A2uOWIUQX3KcG850ElpW4lVtn2uyPpJHZq9cPlpJjMY,15137664
|
|
46
|
-
dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio.so,sha256=ZaWOodGeNlfKsYBluphJEXgcnVyln4ja7Zie3qZZlAU,1596964
|
|
47
|
-
dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis.so,sha256=_OvfcRyZpVT5cTWzIr4YE2XDUcLd2DNCPR3zQv9F2r0,2867604
|
|
48
|
-
dbdicom/external/dcm4che/lib/solaris-sparc/libclib_jiio_vis2.so,sha256=DiCFvkUOcCHUimB5JnQ25F69heRu1-DrZGcOocAwGpc,2778740
|
|
49
|
-
dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio.so,sha256=b0YFloOsXiJM-JxPdskI9AGldY3-xCVgKJJ6gvLHtJI,2109160
|
|
50
|
-
dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis.so,sha256=Bb0Sa67dIJfBOkGY-InrTrqraark4yhWevJFfcjnTP4,2891328
|
|
51
|
-
dbdicom/external/dcm4che/lib/solaris-sparcv9/libclib_jiio_vis2.so,sha256=gnPUsRtHvEXdpCgKRc7yDG5Xv0RZ1APLGMopuWy02SU,2838312
|
|
52
|
-
dbdicom/external/dcm4che/lib/solaris-x86/libclib_jiio.so,sha256=pTeKaa3cjtts-E2nCs-xhJPRdQoSI-OjZSTGjlLWRGU,2162548
|
|
53
|
-
dbdicom/external/dcm4che/lib/solaris-x86-64/libclib_jiio.so,sha256=xTpV49v4Go2U_fw_hJ8OACn3DOLUW5dK2fcNgLJkzAA,1633976
|
|
54
48
|
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio.dll,sha256=C2dAjNyefOm3POrUxorEF6T-FTztpo0nfGAsUrDyQyg,720896
|
|
55
49
|
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_sse2.dll,sha256=uD9GLN_hPf9mM9APzlp9j6770awKP6xnlaooMrxHpkg,1089536
|
|
56
50
|
dbdicom/external/dcm4che/lib/windows-x86/clib_jiio_util.dll,sha256=wi4yyrI1gTRo_bBpj0E097BQBiHZd8IqVifKr6kfkRE,40960
|
|
57
51
|
dbdicom/external/dcm4che/lib/windows-x86/opencv_java.dll,sha256=QanyzLy0Cd79-aOVPwOcXwikUYeutne0Au-Um91_B4M,8505856
|
|
58
52
|
dbdicom/external/dcm4che/lib/windows-x86-64/opencv_java.dll,sha256=TmjW2SbG4MR3GQ95T8xCVVDLgsdKukgaHBPUvWkfXp8,11039232
|
|
59
53
|
dbdicom/types/database.py,sha256=Ur-VE6Uixw4nV6QUY8fnMSUgDvvk54KhiUvbmS3bGuE,3066
|
|
60
|
-
dbdicom/types/instance.py,sha256=
|
|
54
|
+
dbdicom/types/instance.py,sha256=_j38VQqjaJITQX98WyqBqGXvYcpzRP8TRmpZ7wwu5-E,7655
|
|
61
55
|
dbdicom/types/patient.py,sha256=YtBTwJDo8EiquJ2vLcyBW7Pzz7EISKhzvxq2506QSNo,1312
|
|
62
|
-
dbdicom/types/series.py,sha256
|
|
56
|
+
dbdicom/types/series.py,sha256=-GIMoGzgW-SWLZ9VexcB2TjB9pzi953YuzZCBwF1-KI,111898
|
|
63
57
|
dbdicom/types/study.py,sha256=iX6gjA905DBvmTEwxSuppp_E7XXkTHvN3ezAnu362Es,2031
|
|
64
58
|
dbdicom/utils/dcm4che.py,sha256=Vxq8NYWWK3BuqJkzhBQ89oMqzJlnxqTxgsgTo_Frznc,2317
|
|
65
59
|
dbdicom/utils/files.py,sha256=HkAr03EmpcLkfcr6cS13_g-vqbE1acRYmTJP3e5zNas,2844
|
|
66
|
-
dbdicom/utils/image.py,sha256=
|
|
60
|
+
dbdicom/utils/image.py,sha256=IPTD-4adMy5rf5rgSwfR6ImuBZojMfnp4-zKeuG9zik,26385
|
|
67
61
|
dbdicom/utils/variables.py,sha256=vUh5cDnmCft5hoXDYXUvfkg5Cy5WlgMAogU38Y_BKRo,5753
|
|
68
|
-
dbdicom/
|
|
69
|
-
dbdicom/
|
|
70
|
-
dbdicom/
|
|
71
|
-
dbdicom/
|
|
72
|
-
dbdicom/
|
|
73
|
-
dbdicom/wrappers/scipy.py,sha256=vEdw5oLvKhotuA8qyhKdr2JOdRUNeLKZOIbbhsvlOUg,48918
|
|
74
|
-
dbdicom/wrappers/skimage.py,sha256=dgv-Cs6C3RiY60VuaUVHnMPFVIPrSB5acyi5v_g2iTc,38561
|
|
75
|
-
dbdicom/wrappers/sklearn.py,sha256=o1rs6iSaWd0rVdAZsHGvsRtKzmjLd5bLYu3JThAK2-A,5219
|
|
76
|
-
dbdicom/wrappers/vreg.py,sha256=CAhyGUN7mSTzeZXZ58_6TyaQM1LnPTJ8ahFjbyafy2w,11603
|
|
77
|
-
dbdicom-0.2.1.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
78
|
-
dbdicom-0.2.1.dist-info/METADATA,sha256=CMsNBpM5RQlJVyAJdx2XcglcQ7tCJGNBR7bxeeqk67U,16381
|
|
79
|
-
dbdicom-0.2.1.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
80
|
-
dbdicom-0.2.1.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
|
|
81
|
-
dbdicom-0.2.1.dist-info/RECORD,,
|
|
62
|
+
dbdicom-0.2.4.dist-info/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
63
|
+
dbdicom-0.2.4.dist-info/METADATA,sha256=8Gv7ufrnEsiJbQIPs5XN8PbOAO8YgP5URDUvJCLp6ks,3421
|
|
64
|
+
dbdicom-0.2.4.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
65
|
+
dbdicom-0.2.4.dist-info/top_level.txt,sha256=nJWxXg4YjD6QblfmhrzTMXcr8FSKNc0Yk-CAIDUsYkQ,8
|
|
66
|
+
dbdicom-0.2.4.dist-info/RECORD,,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|