66
77import numpy as np
88import torch
9+ from einops import rearrange
910
1011from .data .image import Image
1112from .data .image import LabelMap
@@ -35,7 +36,7 @@ def import_mpl_plt():
3536
3637def rotate (image , radiological = True , n = - 1 ):
3738 # Rotate for visualization purposes
38- image = np .rot90 (image , n )
39+ image = np .rot90 (image , n , axes = ( 0 , 1 ) )
3940 if radiological :
4041 image = np .fliplr (image )
4142 return image
@@ -59,17 +60,18 @@ def _create_categorical_colormap(data: torch.Tensor) -> ListedColormap:
5960def plot_volume (
6061 image : Image ,
6162 radiological = True ,
62- channel = - 1 , # default to foreground for binary maps
63+ channel = None ,
6364 axes = None ,
6465 cmap = None ,
6566 output_path = None ,
6667 show = True ,
6768 xlabels = True ,
68- percentiles : tuple [float , float ] = (0.5 , 99.5 ),
69+ percentiles : tuple [float , float ] = (0 , 100 ),
6970 figsize = None ,
7071 title = None ,
7172 reorient = True ,
7273 indices = None ,
74+ rgb = True ,
7375 ** imshow_kwargs ,
7476):
7577 _ , plt = import_mpl_plt ()
@@ -80,14 +82,25 @@ def plot_volume(
8082
8183 if reorient :
8284 image = ToCanonical ()(image ) # type: ignore[assignment]
83- data = image .data [channel ]
85+
86+ is_label = isinstance (image , LabelMap )
87+ if is_label : # probabilistic label map
88+ data = image .data [np .newaxis , - 1 ]
89+ elif rgb and image .num_channels == 3 :
90+ data = image .data # keep image as it is
91+ elif channel is None :
92+ data = image .data [0 :1 ] # just use the first channel
93+ else :
94+ data = image .data [np .newaxis , channel ]
95+ data = rearrange (data , 'c x y z -> x y z c' )
96+
8497 if indices is None :
85- indices = np .array (data .shape ) // 2
98+ indices = np .array (data .shape [: 3 ] ) // 2
8699 i , j , k = indices
87100 slice_x = rotate (data [i , :, :], radiological = radiological )
88101 slice_y = rotate (data [:, j , :], radiological = radiological )
89102 slice_z = rotate (data [:, :, k ], radiological = radiological )
90- is_label = isinstance ( image , LabelMap )
103+
91104 if isinstance (cmap , dict ):
92105 slices = slice_x , slice_y , slice_z
93106 slice_x , slice_y , slice_z = color_labels (slices , cmap )
@@ -98,6 +111,9 @@ def plot_volume(
98111
99112 if is_label :
100113 imshow_kwargs ['interpolation' ] = 'none'
114+ else :
115+ if 'interpolation' not in imshow_kwargs :
116+ imshow_kwargs ['interpolation' ] = 'bicubic'
101117
102118 sr , sa , ss = image .spacing
103119 imshow_kwargs ['origin' ] = 'lower'
@@ -108,23 +124,35 @@ def plot_volume(
108124 imshow_kwargs ['vmax' ] = p2
109125
110126 sag_aspect = ss / sa
111- sag_axis .imshow (slice_x , aspect = sag_aspect , ** imshow_kwargs )
127+ sag_axis .imshow (
128+ slice_x ,
129+ aspect = sag_aspect ,
130+ ** imshow_kwargs ,
131+ )
112132 if xlabels :
113133 sag_axis .set_xlabel ('A' )
114134 sag_axis .set_ylabel ('S' )
115135 sag_axis .invert_xaxis ()
116136 sag_axis .set_title ('Sagittal' )
117137
118138 cor_aspect = ss / sr
119- cor_axis .imshow (slice_y , aspect = cor_aspect , ** imshow_kwargs )
139+ cor_axis .imshow (
140+ slice_y ,
141+ aspect = cor_aspect ,
142+ ** imshow_kwargs ,
143+ )
120144 if xlabels :
121145 cor_axis .set_xlabel ('R' )
122146 cor_axis .set_ylabel ('S' )
123147 cor_axis .invert_xaxis ()
124148 cor_axis .set_title ('Coronal' )
125149
126150 axi_aspect = sa / sr
127- axi_axis .imshow (slice_z , aspect = axi_aspect , ** imshow_kwargs )
151+ axi_axis .imshow (
152+ slice_z ,
153+ aspect = axi_aspect ,
154+ ** imshow_kwargs ,
155+ )
128156 if xlabels :
129157 axi_axis .set_xlabel ('R' )
130158 axi_axis .set_ylabel ('A' )
@@ -223,15 +251,15 @@ def plot_histogram(x: np.ndarray, show=True, **kwargs) -> None:
223251
224252def color_labels (arrays , cmap_dict ):
225253 results = []
226- for array in arrays :
227- si , sj = array .shape
254+ for slice_array in arrays :
255+ si , sj , _ = slice_array .shape
228256 rgb = np .zeros ((si , sj , 3 ), dtype = np .uint8 )
229257 for label , color in cmap_dict .items ():
230258 if isinstance (color , str ):
231259 mpl , _ = import_mpl_plt ()
232260 color = mpl .colors .to_rgb (color )
233261 color = [255 * n for n in color ]
234- rgb [array == label ] = color
262+ rgb [slice_array [..., 0 ] == label ] = color
235263 results .append (rgb )
236264 return results
237265
0 commit comments