miblab-plot 0.0.9__tar.gz → 0.0.11__tar.gz
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.
- {miblab_plot-0.0.9/src/miblab_plot.egg-info → miblab_plot-0.0.11}/PKG-INFO +1 -2
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/pyproject.toml +1 -2
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/__init__.py +1 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/image_3d.py +61 -1
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/pvplot.py +4 -57
- {miblab_plot-0.0.9 → miblab_plot-0.0.11/src/miblab_plot.egg-info}/PKG-INFO +1 -2
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot.egg-info/requires.txt +0 -1
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/LICENSE +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/README.md +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/setup.cfg +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/gui.py +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/movie.py +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot/mp4.py +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot.egg-info/SOURCES.txt +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot.egg-info/dependency_links.txt +0 -0
- {miblab_plot-0.0.9 → miblab_plot-0.0.11}/src/miblab_plot.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: miblab-plot
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11
|
|
4
4
|
Summary: Plotting utilities for medical images
|
|
5
5
|
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -26,7 +26,6 @@ Requires-Dist: imageio
|
|
|
26
26
|
Requires-Dist: zarr
|
|
27
27
|
Requires-Dist: pillow
|
|
28
28
|
Requires-Dist: dbdicom
|
|
29
|
-
Requires-Dist: miblab_ssa
|
|
30
29
|
Dynamic: license-file
|
|
31
30
|
|
|
32
31
|
# miblab-plot
|
|
@@ -6,7 +6,7 @@ requires = ['setuptools>=61.2']
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "miblab-plot"
|
|
9
|
-
version = "0.0.
|
|
9
|
+
version = "0.0.11"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"numpy",
|
|
12
12
|
"matplotlib",
|
|
@@ -18,7 +18,6 @@ dependencies = [
|
|
|
18
18
|
"zarr",
|
|
19
19
|
"pillow",
|
|
20
20
|
"dbdicom",
|
|
21
|
-
"miblab_ssa",
|
|
22
21
|
]
|
|
23
22
|
|
|
24
23
|
# optional information
|
|
@@ -6,9 +6,67 @@ import matplotlib
|
|
|
6
6
|
matplotlib.use('Agg')
|
|
7
7
|
import matplotlib.pyplot as plt
|
|
8
8
|
from tqdm import tqdm
|
|
9
|
+
import dbdicom as db
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
def db_mosaic(series_to_display, pngfile, title="Center slices"):
|
|
14
|
+
|
|
15
|
+
# Build list of center slices
|
|
16
|
+
center_slices = []
|
|
17
|
+
for series in tqdm(series_to_display, desc='Reading center images'):
|
|
18
|
+
vol = db.volume(series, verbose=0)
|
|
19
|
+
center_slice = vol.values[:,:,round(vol.shape[-1]/2)]
|
|
20
|
+
center_slices.append(center_slice)
|
|
21
|
+
|
|
22
|
+
# Display center slices as mosaic
|
|
23
|
+
n_imgs = len(center_slices)
|
|
24
|
+
aspect_ratio = 16/9
|
|
25
|
+
nrows = int(np.ceil(np.sqrt(n_imgs / aspect_ratio)))
|
|
26
|
+
ncols = int(np.ceil(aspect_ratio * nrows))
|
|
27
|
+
fig, ax = plt.subplots(nrows=nrows, ncols=ncols, gridspec_kw = {'wspace':0, 'hspace':0}, figsize=(ncols, nrows), dpi=300)
|
|
28
|
+
|
|
29
|
+
i=0
|
|
30
|
+
for row in tqdm(ax, desc='Building png'):
|
|
31
|
+
for col in row:
|
|
32
|
+
|
|
33
|
+
col.set_xticklabels([])
|
|
34
|
+
col.set_yticklabels([])
|
|
35
|
+
col.set_aspect('equal')
|
|
36
|
+
col.axis("off")
|
|
37
|
+
|
|
38
|
+
if i < len(center_slices):
|
|
39
|
+
|
|
40
|
+
# Show center image
|
|
41
|
+
col.imshow(
|
|
42
|
+
center_slices[i].T,
|
|
43
|
+
cmap='gray',
|
|
44
|
+
interpolation='none',
|
|
45
|
+
vmin=0,
|
|
46
|
+
vmax=np.mean(center_slices[i]) + 2 * np.std(center_slices[i])
|
|
47
|
+
)
|
|
48
|
+
# Add white text with black background in upper-left corner
|
|
49
|
+
patient_id = series_to_display[i][1]
|
|
50
|
+
series_desc = series_to_display[i][-1][0]
|
|
51
|
+
study = series_to_display[i][2][0]
|
|
52
|
+
col.text(
|
|
53
|
+
0.01, 0.99,
|
|
54
|
+
f'{patient_id}_{study}\n{series_desc}',
|
|
55
|
+
color='white',
|
|
56
|
+
fontsize=2,
|
|
57
|
+
ha='left',
|
|
58
|
+
va='top',
|
|
59
|
+
transform=col.transAxes, # Use axes coordinates
|
|
60
|
+
bbox=dict(facecolor='black', alpha=0.7, boxstyle='round,pad=0.3')
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
i+=1
|
|
64
|
+
|
|
65
|
+
fig.suptitle(title, fontsize=14)
|
|
66
|
+
fig.savefig(pngfile)
|
|
67
|
+
plt.close()
|
|
68
|
+
|
|
69
|
+
|
|
12
70
|
def get_distinct_colors(rois, colormap='jet', opacity=0.6):
|
|
13
71
|
if len(rois)==1:
|
|
14
72
|
colors = [[1, 0, 0, opacity]]
|
|
@@ -165,6 +223,7 @@ def mosaic_overlay(
|
|
|
165
223
|
vmin=None,
|
|
166
224
|
vmax=None,
|
|
167
225
|
opacity=0.6,
|
|
226
|
+
colors=None
|
|
168
227
|
):
|
|
169
228
|
|
|
170
229
|
# Set defaults color window
|
|
@@ -174,7 +233,8 @@ def mosaic_overlay(
|
|
|
174
233
|
vmax=np.mean(img) + 2 * np.std(img)
|
|
175
234
|
|
|
176
235
|
# Define RGBA colors (R, G, B, Alpha) — alpha controls transparency
|
|
177
|
-
colors
|
|
236
|
+
if colors is None:
|
|
237
|
+
colors = get_distinct_colors(rois, colormap=colormap, opacity=opacity)
|
|
178
238
|
|
|
179
239
|
# Get all masks as boolean arrays
|
|
180
240
|
masks = [m.astype(bool) for m in rois.values()]
|
|
@@ -8,8 +8,6 @@ import pyvista as pv
|
|
|
8
8
|
import dbdicom as db
|
|
9
9
|
import zarr
|
|
10
10
|
|
|
11
|
-
import miblab_ssa as ssa
|
|
12
|
-
|
|
13
11
|
|
|
14
12
|
def setup_rendering_env():
|
|
15
13
|
|
|
@@ -68,7 +66,7 @@ def mosaic_masks_dcm(masks, imagefile, labels=None, view_vector=(1, 0, 0)):
|
|
|
68
66
|
|
|
69
67
|
# Load data
|
|
70
68
|
vol = db.volume(mask_series, verbose=0)
|
|
71
|
-
mask_norm =
|
|
69
|
+
mask_norm = vol.values
|
|
72
70
|
|
|
73
71
|
# Plot tile
|
|
74
72
|
orig_vol = pv.wrap(mask_norm.astype(float))
|
|
@@ -202,8 +200,7 @@ def multiple_mosaic_masks_da(masks: list, directions: dict, labels, columns=None
|
|
|
202
200
|
|
|
203
201
|
surfaces = []
|
|
204
202
|
for mask_series in tqdm(masks, desc="Pre-calculating Surfaces"):
|
|
205
|
-
|
|
206
|
-
#mask_norm = ssa.sdf_ft.smooth_mask(mask_series[:].astype(bool), order=16)
|
|
203
|
+
|
|
207
204
|
mask_norm = mask_series[:].astype(bool)
|
|
208
205
|
|
|
209
206
|
vol = pv.wrap(mask_norm.astype(np.float32))
|
|
@@ -327,7 +324,7 @@ def multiple_mosaic_masks_npz(masks, directions:dict, labels, columns=None, rows
|
|
|
327
324
|
|
|
328
325
|
# Load data once
|
|
329
326
|
vol = db.npz.volume(mask_series)
|
|
330
|
-
mask_norm =
|
|
327
|
+
mask_norm = vol.values.astype(bool)
|
|
331
328
|
|
|
332
329
|
orig_vol = pv.wrap(mask_norm.astype(float))
|
|
333
330
|
orig_vol.spacing = [1.0, 1.0, 1.0]
|
|
@@ -443,7 +440,7 @@ def mosaic_masks_npz(masks, imagefile, labels=None, view_vector=(1, 0, 0)):
|
|
|
443
440
|
|
|
444
441
|
# Load data
|
|
445
442
|
vol = db.npz.volume(mask_series)
|
|
446
|
-
mask_norm =
|
|
443
|
+
mask_norm = vol.values.astype(bool)
|
|
447
444
|
|
|
448
445
|
# Plot tile
|
|
449
446
|
orig_vol = pv.wrap(mask_norm.astype(float))
|
|
@@ -456,53 +453,3 @@ def mosaic_masks_npz(masks, imagefile, labels=None, view_vector=(1, 0, 0)):
|
|
|
456
453
|
plotter.screenshot(imagefile)
|
|
457
454
|
plotter.close()
|
|
458
455
|
|
|
459
|
-
|
|
460
|
-
def mosaic_features_npz(features, imagefile, labels=None, view_vector=(1, 0, 0)):
|
|
461
|
-
|
|
462
|
-
# Plot settings
|
|
463
|
-
aspect_ratio = 16/9
|
|
464
|
-
width = 150
|
|
465
|
-
height = 150
|
|
466
|
-
|
|
467
|
-
# Count nr of mosaics
|
|
468
|
-
n_mosaics = len(features)
|
|
469
|
-
nrows = int(np.ceil(np.sqrt((width*n_mosaics)/(aspect_ratio*height))))
|
|
470
|
-
ncols = int(np.ceil(n_mosaics/nrows))
|
|
471
|
-
|
|
472
|
-
plotter = pv.Plotter(
|
|
473
|
-
window_size=(ncols*width, nrows*height),
|
|
474
|
-
shape=(nrows, ncols),
|
|
475
|
-
border=False,
|
|
476
|
-
# off_screen=True,
|
|
477
|
-
off_screen=pv.OFF_SCREEN,
|
|
478
|
-
)
|
|
479
|
-
plotter.background_color = 'white'
|
|
480
|
-
|
|
481
|
-
row = 0
|
|
482
|
-
col = 0
|
|
483
|
-
for i, feat in tqdm(enumerate(features), desc=f'Building mosaic'):
|
|
484
|
-
|
|
485
|
-
# Set up plotter
|
|
486
|
-
plotter.subplot(row,col)
|
|
487
|
-
if labels is not None:
|
|
488
|
-
plotter.add_text(labels[i], font_size=6)
|
|
489
|
-
if col == ncols-1:
|
|
490
|
-
col = 0
|
|
491
|
-
row += 1
|
|
492
|
-
else:
|
|
493
|
-
col += 1
|
|
494
|
-
|
|
495
|
-
# Load data
|
|
496
|
-
ft = np.load(feat)
|
|
497
|
-
mask_norm = ssa.sdf_ft.mask_from_features(ft['features'], ft['shape'], ft['order'])
|
|
498
|
-
|
|
499
|
-
# Plot tile
|
|
500
|
-
orig_vol = pv.wrap(mask_norm.astype(float))
|
|
501
|
-
orig_vol.spacing = [1.0, 1.0, 1.0]
|
|
502
|
-
orig_surface = orig_vol.contour(isosurfaces=[0.5])
|
|
503
|
-
plotter.add_mesh(orig_surface, color='lightblue', opacity=1.0, style='surface')
|
|
504
|
-
plotter.camera_position = 'iso'
|
|
505
|
-
plotter.view_vector(view_vector) # rotate 180° around vertical axis
|
|
506
|
-
|
|
507
|
-
plotter.screenshot(imagefile)
|
|
508
|
-
plotter.close()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: miblab-plot
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.11
|
|
4
4
|
Summary: Plotting utilities for medical images
|
|
5
5
|
Author-email: Steven Sourbron <s.sourbron@sheffield.ac.uk>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -26,7 +26,6 @@ Requires-Dist: imageio
|
|
|
26
26
|
Requires-Dist: zarr
|
|
27
27
|
Requires-Dist: pillow
|
|
28
28
|
Requires-Dist: dbdicom
|
|
29
|
-
Requires-Dist: miblab_ssa
|
|
30
29
|
Dynamic: license-file
|
|
31
30
|
|
|
32
31
|
# miblab-plot
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|