fastMONAI 0.5.4__py3-none-any.whl → 0.6.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.
- fastMONAI/__init__.py +1 -1
- fastMONAI/_modidx.py +53 -1
- fastMONAI/dataset_info.py +144 -7
- fastMONAI/utils.py +296 -7
- fastMONAI/vision_augmentation.py +137 -5
- fastMONAI/vision_patch.py +157 -23
- fastMONAI/vision_plot.py +89 -1
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.0.dist-info}/METADATA +1 -1
- fastmonai-0.6.0.dist-info/RECORD +21 -0
- fastmonai-0.5.4.dist-info/RECORD +0 -21
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.0.dist-info}/WHEEL +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.0.dist-info}/entry_points.txt +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.0.dist-info}/licenses/LICENSE +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.0.dist-info}/top_level.txt +0 -0
fastMONAI/vision_patch.py
CHANGED
|
@@ -18,8 +18,10 @@ from typing import Callable
|
|
|
18
18
|
from torch.utils.data import DataLoader
|
|
19
19
|
from tqdm.auto import tqdm
|
|
20
20
|
from fastai.data.all import *
|
|
21
|
+
from fastai.learner import Learner
|
|
21
22
|
from .vision_core import MedImage, MedMask, MedBase, med_img_reader
|
|
22
23
|
from .vision_inference import _to_original_orientation, _do_resize
|
|
24
|
+
from .dataset_info import MedDataset, suggest_patch_size
|
|
23
25
|
|
|
24
26
|
# %% ../nbs/10_vision_patch.ipynb 3
|
|
25
27
|
def _get_default_device() -> torch.device:
|
|
@@ -109,7 +111,7 @@ class PatchConfig:
|
|
|
109
111
|
queue_num_workers: Number of workers for parallel patch extraction.
|
|
110
112
|
aggregation_mode: For inference, how to combine overlapping patches ('crop', 'average', 'hann').
|
|
111
113
|
apply_reorder: Whether to reorder to RAS+ canonical orientation. Must match between
|
|
112
|
-
training and inference.
|
|
114
|
+
training and inference. Defaults to True (the common case).
|
|
113
115
|
target_spacing: Target voxel spacing [x, y, z] for resampling. Must match between
|
|
114
116
|
training and inference.
|
|
115
117
|
padding_mode: Padding mode for CropOrPad when image < patch_size. Default is 0 (zero padding)
|
|
@@ -124,7 +126,6 @@ class PatchConfig:
|
|
|
124
126
|
... samples_per_volume=16,
|
|
125
127
|
... sampler_type='label',
|
|
126
128
|
... label_probabilities={0: 0.1, 1: 0.9},
|
|
127
|
-
... apply_reorder=True,
|
|
128
129
|
... target_spacing=[0.5, 0.5, 0.5]
|
|
129
130
|
... )
|
|
130
131
|
"""
|
|
@@ -137,7 +138,7 @@ class PatchConfig:
|
|
|
137
138
|
queue_num_workers: int = 4
|
|
138
139
|
aggregation_mode: str = 'hann'
|
|
139
140
|
# Preprocessing parameters - must match between training and inference
|
|
140
|
-
apply_reorder: bool =
|
|
141
|
+
apply_reorder: bool = True # Defaults to True (the common case)
|
|
141
142
|
target_spacing: list = None
|
|
142
143
|
padding_mode: int | float | str = 0 # Zero padding (nnU-Net standard)
|
|
143
144
|
# Post-processing (binary segmentation only)
|
|
@@ -176,6 +177,74 @@ class PatchConfig:
|
|
|
176
177
|
f"Overlap >= patch_size creates step_size <= 0 (infinite patches)."
|
|
177
178
|
)
|
|
178
179
|
|
|
180
|
+
@classmethod
|
|
181
|
+
def from_dataset(
|
|
182
|
+
cls,
|
|
183
|
+
dataset: 'MedDataset',
|
|
184
|
+
target_spacing: list = None,
|
|
185
|
+
min_patch_size: list = None,
|
|
186
|
+
max_patch_size: list = None,
|
|
187
|
+
divisor: int = 16,
|
|
188
|
+
**kwargs
|
|
189
|
+
) -> 'PatchConfig':
|
|
190
|
+
"""Create PatchConfig with automatic patch_size from dataset analysis.
|
|
191
|
+
|
|
192
|
+
Combines dataset preprocessing suggestions with patch size calculation
|
|
193
|
+
for a complete, DRY configuration.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
dataset: MedDataset instance with analyzed images.
|
|
197
|
+
target_spacing: Target voxel spacing [x, y, z]. If None, uses
|
|
198
|
+
dataset.get_suggestion()['target_spacing'].
|
|
199
|
+
min_patch_size: Minimum per dimension [32, 32, 32].
|
|
200
|
+
max_patch_size: Maximum per dimension [256, 256, 256].
|
|
201
|
+
divisor: Divisibility constraint (default 16 for UNet compatibility).
|
|
202
|
+
**kwargs: Additional PatchConfig parameters (samples_per_volume,
|
|
203
|
+
sampler_type, label_probabilities, etc.).
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
PatchConfig with suggested patch_size, apply_reorder, target_spacing.
|
|
207
|
+
|
|
208
|
+
Example:
|
|
209
|
+
>>> from fastMONAI.dataset_info import MedDataset
|
|
210
|
+
>>> dataset = MedDataset(dataframe=df, mask_col='mask_path', dtype=MedMask)
|
|
211
|
+
>>>
|
|
212
|
+
>>> # Use recommended spacing
|
|
213
|
+
>>> config = PatchConfig.from_dataset(dataset, samples_per_volume=16)
|
|
214
|
+
>>>
|
|
215
|
+
>>> # Use custom spacing
|
|
216
|
+
>>> config = PatchConfig.from_dataset(
|
|
217
|
+
... dataset,
|
|
218
|
+
... target_spacing=[1.0, 1.0, 2.0],
|
|
219
|
+
... samples_per_volume=16
|
|
220
|
+
... )
|
|
221
|
+
"""
|
|
222
|
+
# Get preprocessing suggestion from dataset
|
|
223
|
+
suggestion = dataset.get_suggestion()
|
|
224
|
+
|
|
225
|
+
# Use explicit spacing or dataset suggestion
|
|
226
|
+
_target_spacing = target_spacing if target_spacing is not None else suggestion['target_spacing']
|
|
227
|
+
|
|
228
|
+
# Calculate patch size for the target spacing
|
|
229
|
+
patch_size = suggest_patch_size(
|
|
230
|
+
dataset,
|
|
231
|
+
target_spacing=_target_spacing,
|
|
232
|
+
min_patch_size=min_patch_size,
|
|
233
|
+
max_patch_size=max_patch_size,
|
|
234
|
+
divisor=divisor
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# Merge with explicit kwargs (kwargs override defaults)
|
|
238
|
+
# Use dataset.apply_reorder directly (not from get_suggestion() since it's not data-derived)
|
|
239
|
+
config_kwargs = {
|
|
240
|
+
'patch_size': patch_size,
|
|
241
|
+
'apply_reorder': dataset.apply_reorder,
|
|
242
|
+
'target_spacing': _target_spacing,
|
|
243
|
+
}
|
|
244
|
+
config_kwargs.update(kwargs)
|
|
245
|
+
|
|
246
|
+
return cls(**config_kwargs)
|
|
247
|
+
|
|
179
248
|
# %% ../nbs/10_vision_patch.ipynb 10
|
|
180
249
|
def med_to_subject(
|
|
181
250
|
img: Path | str,
|
|
@@ -374,6 +443,9 @@ class MedPatchDataLoader:
|
|
|
374
443
|
drop_last=drop_last
|
|
375
444
|
)
|
|
376
445
|
|
|
446
|
+
# Track cleanup state
|
|
447
|
+
self._closed = False
|
|
448
|
+
|
|
377
449
|
def __iter__(self):
|
|
378
450
|
"""Iterate over batches, yielding (image, mask) tuples."""
|
|
379
451
|
for batch in self._dl:
|
|
@@ -444,6 +516,31 @@ class MedPatchDataLoader:
|
|
|
444
516
|
"""
|
|
445
517
|
return next(iter(self))
|
|
446
518
|
|
|
519
|
+
def close(self):
|
|
520
|
+
"""Shut down TorchIO Queue workers. Safe to call multiple times."""
|
|
521
|
+
if self._closed:
|
|
522
|
+
return
|
|
523
|
+
self._closed = True
|
|
524
|
+
try:
|
|
525
|
+
# Trigger cleanup of Queue's internal DataLoader iterator
|
|
526
|
+
if hasattr(self, 'queue') and hasattr(self.queue, '_subjects_iterable'):
|
|
527
|
+
self.queue._subjects_iterable = None
|
|
528
|
+
except Exception:
|
|
529
|
+
pass # Suppress cleanup errors
|
|
530
|
+
|
|
531
|
+
def __enter__(self):
|
|
532
|
+
return self
|
|
533
|
+
|
|
534
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
535
|
+
self.close()
|
|
536
|
+
return False
|
|
537
|
+
|
|
538
|
+
def __del__(self):
|
|
539
|
+
try:
|
|
540
|
+
self.close()
|
|
541
|
+
except Exception:
|
|
542
|
+
pass
|
|
543
|
+
|
|
447
544
|
# %% ../nbs/10_vision_patch.ipynb 18
|
|
448
545
|
class MedPatchDataLoaders:
|
|
449
546
|
"""fastai-compatible DataLoaders for patch-based training with LAZY loading.
|
|
@@ -491,6 +588,9 @@ class MedPatchDataLoaders:
|
|
|
491
588
|
self._train_dl.to(self._device)
|
|
492
589
|
self._valid_dl.to(self._device)
|
|
493
590
|
|
|
591
|
+
# Track cleanup state
|
|
592
|
+
self._closed = False
|
|
593
|
+
|
|
494
594
|
@classmethod
|
|
495
595
|
def from_df(
|
|
496
596
|
cls,
|
|
@@ -528,6 +628,7 @@ class MedPatchDataLoaders:
|
|
|
528
628
|
target_spacing) can be set here for DRY usage with PatchInferenceEngine.
|
|
529
629
|
pre_patch_tfms: TorchIO transforms applied before patch extraction
|
|
530
630
|
(after reorder/resample). Example: [tio.ZNormalization()].
|
|
631
|
+
Accepts both fastMONAI wrappers and raw TorchIO transforms.
|
|
531
632
|
patch_tfms: TorchIO transforms applied to extracted patches (training only).
|
|
532
633
|
apply_reorder: If True, reorder to RAS+ orientation. If None, uses
|
|
533
634
|
patch_config.apply_reorder. Explicit value overrides config.
|
|
@@ -595,9 +696,9 @@ class MedPatchDataLoaders:
|
|
|
595
696
|
if _target_spacing is not None:
|
|
596
697
|
all_pre_tfms.append(tio.Resample(_target_spacing))
|
|
597
698
|
|
|
598
|
-
# Add user-provided transforms
|
|
699
|
+
# Add user-provided transforms (normalize to raw TorchIO transforms)
|
|
599
700
|
if pre_patch_tfms:
|
|
600
|
-
all_pre_tfms.extend(pre_patch_tfms)
|
|
701
|
+
all_pre_tfms.extend(normalize_patch_transforms(pre_patch_tfms))
|
|
601
702
|
|
|
602
703
|
# Create subjects datasets with lazy loading (paths only, ~0 MB)
|
|
603
704
|
train_subjects = create_subjects_dataset(
|
|
@@ -743,9 +844,35 @@ class MedPatchDataLoaders:
|
|
|
743
844
|
def to(self, device):
|
|
744
845
|
self._device = device
|
|
745
846
|
return self
|
|
847
|
+
def cpu(self):
|
|
848
|
+
"""Move to CPU. Required for load_learner compatibility."""
|
|
849
|
+
return self.to(torch.device('cpu'))
|
|
746
850
|
|
|
747
851
|
return EmptyMedPatchDataLoaders(self._device)
|
|
748
852
|
|
|
853
|
+
def close(self):
|
|
854
|
+
"""Shut down all DataLoader workers. Safe to call multiple times."""
|
|
855
|
+
if self._closed:
|
|
856
|
+
return
|
|
857
|
+
self._closed = True
|
|
858
|
+
if hasattr(self, '_train_dl') and self._train_dl is not None:
|
|
859
|
+
self._train_dl.close()
|
|
860
|
+
if hasattr(self, '_valid_dl') and self._valid_dl is not None:
|
|
861
|
+
self._valid_dl.close()
|
|
862
|
+
|
|
863
|
+
def __enter__(self):
|
|
864
|
+
return self
|
|
865
|
+
|
|
866
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
867
|
+
self.close()
|
|
868
|
+
return False
|
|
869
|
+
|
|
870
|
+
def __del__(self):
|
|
871
|
+
try:
|
|
872
|
+
self.close()
|
|
873
|
+
except Exception:
|
|
874
|
+
pass
|
|
875
|
+
|
|
749
876
|
# %% ../nbs/10_vision_patch.ipynb 20
|
|
750
877
|
import numbers
|
|
751
878
|
|
|
@@ -806,7 +933,8 @@ class PatchInferenceEngine:
|
|
|
806
933
|
GridAggregator to reconstruct the full volume from predictions.
|
|
807
934
|
|
|
808
935
|
Args:
|
|
809
|
-
learner: PyTorch model
|
|
936
|
+
learner: fastai Learner or PyTorch model (nn.Module). When passing a raw
|
|
937
|
+
PyTorch model, load weights first with model.load_state_dict().
|
|
810
938
|
config: PatchConfig with inference settings. Preprocessing params (apply_reorder,
|
|
811
939
|
target_spacing, padding_mode) can be set here for DRY usage.
|
|
812
940
|
apply_reorder: Whether to reorder to RAS+ orientation. If None, uses config value.
|
|
@@ -815,21 +943,18 @@ class PatchInferenceEngine:
|
|
|
815
943
|
pre_inference_tfms: List of TorchIO transforms to apply before patch extraction.
|
|
816
944
|
IMPORTANT: Should match the pre_patch_tfms used during training (e.g., [tio.ZNormalization()]).
|
|
817
945
|
This ensures preprocessing consistency between training and inference.
|
|
946
|
+
Accepts both fastMONAI wrappers and raw TorchIO transforms.
|
|
818
947
|
|
|
819
948
|
Example:
|
|
820
|
-
>>> #
|
|
821
|
-
>>>
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
...
|
|
826
|
-
>>>
|
|
827
|
-
>>>
|
|
828
|
-
>>>
|
|
829
|
-
>>> engine = PatchInferenceEngine(
|
|
830
|
-
... learn, config,
|
|
831
|
-
... pre_inference_tfms=[tio.ZNormalization()]
|
|
832
|
-
... )
|
|
949
|
+
>>> # Option 1: From fastai Learner
|
|
950
|
+
>>> engine = PatchInferenceEngine(learn, config, pre_inference_tfms=[ZNormalization()])
|
|
951
|
+
>>> pred = engine.predict('image.nii.gz')
|
|
952
|
+
|
|
953
|
+
>>> # Option 2: From raw PyTorch model (recommended for deployment)
|
|
954
|
+
>>> model = UNet(spatial_dims=3, in_channels=1, out_channels=2, ...)
|
|
955
|
+
>>> model.load_state_dict(torch.load('weights.pth'))
|
|
956
|
+
>>> model.cuda().eval()
|
|
957
|
+
>>> engine = PatchInferenceEngine(model, config, pre_inference_tfms=[ZNormalization()])
|
|
833
958
|
>>> pred = engine.predict('image.nii.gz')
|
|
834
959
|
"""
|
|
835
960
|
|
|
@@ -845,11 +970,20 @@ class PatchInferenceEngine:
|
|
|
845
970
|
if batch_size <= 0:
|
|
846
971
|
raise ValueError(f"batch_size must be positive, got {batch_size}")
|
|
847
972
|
|
|
848
|
-
# Extract model from Learner if needed
|
|
849
|
-
|
|
973
|
+
# Extract model from Learner if needed (use isinstance for robust detection)
|
|
974
|
+
# Note: We check for Learner explicitly because some models (e.g., MONAI UNet)
|
|
975
|
+
# have a .model attribute that is NOT the full model but an internal Sequential.
|
|
976
|
+
if isinstance(learner, Learner):
|
|
977
|
+
self.model = learner.model
|
|
978
|
+
else:
|
|
979
|
+
self.model = learner # Assume it's already a PyTorch model
|
|
980
|
+
|
|
850
981
|
self.config = config
|
|
851
982
|
self.batch_size = batch_size
|
|
852
|
-
|
|
983
|
+
|
|
984
|
+
# Normalize transforms to raw TorchIO (accepts both fastMONAI wrappers and raw TorchIO)
|
|
985
|
+
normalized_tfms = normalize_patch_transforms(pre_inference_tfms)
|
|
986
|
+
self.pre_inference_tfms = tio.Compose(normalized_tfms) if normalized_tfms else None
|
|
853
987
|
|
|
854
988
|
# Use config values, allow explicit overrides for backward compatibility
|
|
855
989
|
self.apply_reorder = apply_reorder if apply_reorder is not None else config.apply_reorder
|
|
@@ -1024,7 +1158,7 @@ class PatchInferenceEngine:
|
|
|
1024
1158
|
self.model.to(device)
|
|
1025
1159
|
return self
|
|
1026
1160
|
|
|
1027
|
-
# %% ../nbs/10_vision_patch.ipynb
|
|
1161
|
+
# %% ../nbs/10_vision_patch.ipynb 22
|
|
1028
1162
|
def patch_inference(
|
|
1029
1163
|
learner,
|
|
1030
1164
|
config: PatchConfig,
|
fastMONAI/vision_plot.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_vision_plot.ipynb.
|
|
2
2
|
|
|
3
3
|
# %% auto 0
|
|
4
|
-
__all__ = ['validate_anatomical_plane', 'show_med_img', 'find_max_slice']
|
|
4
|
+
__all__ = ['validate_anatomical_plane', 'show_med_img', 'find_max_slice', 'show_segmentation_comparison']
|
|
5
5
|
|
|
6
6
|
# %% ../nbs/00_vision_plot.ipynb 1
|
|
7
7
|
import warnings
|
|
@@ -115,3 +115,91 @@ def find_max_slice(mask_data, anatomical_plane):
|
|
|
115
115
|
idx = np.argmax(sums)
|
|
116
116
|
|
|
117
117
|
return idx
|
|
118
|
+
|
|
119
|
+
# %% ../nbs/00_vision_plot.ipynb 7
|
|
120
|
+
def show_segmentation_comparison(
|
|
121
|
+
image, ground_truth, prediction,
|
|
122
|
+
slice_index: int = None,
|
|
123
|
+
anatomical_plane: int = 2,
|
|
124
|
+
metric_value: float = None,
|
|
125
|
+
metric_name: str = 'DSC',
|
|
126
|
+
channel: int = 0,
|
|
127
|
+
figsize: tuple = (15, 5),
|
|
128
|
+
cmap_img: str = 'gray',
|
|
129
|
+
cmap_mask: str = 'gray',
|
|
130
|
+
voxel_size = None
|
|
131
|
+
):
|
|
132
|
+
"""Display 3-panel comparison: Image | Ground Truth | Prediction.
|
|
133
|
+
|
|
134
|
+
Useful for validating segmentation results, especially after patch-based
|
|
135
|
+
inference where results are not in standard fastai batch format.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
image: Input image (MedImage, MedMask, or tensor [C, H, W, D])
|
|
139
|
+
ground_truth: Ground truth mask (MedMask or tensor [C, H, W, D])
|
|
140
|
+
prediction: Predicted mask (tensor [C, H, W, D])
|
|
141
|
+
slice_index: Slice to display. If None, uses find_max_slice on ground_truth.
|
|
142
|
+
anatomical_plane: 0=sagittal, 1=coronal, 2=axial (default)
|
|
143
|
+
metric_value: Optional metric value to display in prediction title
|
|
144
|
+
metric_name: Name of metric for title (default 'DSC')
|
|
145
|
+
channel: Channel to display for multi-channel data (default 0)
|
|
146
|
+
figsize: Figure size (default (15, 5))
|
|
147
|
+
cmap_img: Colormap for image (default 'gray')
|
|
148
|
+
cmap_mask: Colormap for masks (default 'gray')
|
|
149
|
+
voxel_size: Voxel spacing for aspect ratio. If None, aspect=1.
|
|
150
|
+
|
|
151
|
+
Example::
|
|
152
|
+
|
|
153
|
+
# After patch_inference()
|
|
154
|
+
show_segmentation_comparison(
|
|
155
|
+
image=val_img,
|
|
156
|
+
ground_truth=val_gt,
|
|
157
|
+
prediction=predictions[0],
|
|
158
|
+
metric_value=results_df.iloc[0]['DSC'],
|
|
159
|
+
anatomical_plane=2
|
|
160
|
+
)
|
|
161
|
+
"""
|
|
162
|
+
validate_anatomical_plane(anatomical_plane)
|
|
163
|
+
|
|
164
|
+
# Ensure we have tensor data
|
|
165
|
+
img_data = image.data if hasattr(image, 'data') else image
|
|
166
|
+
gt_data = ground_truth.data if hasattr(ground_truth, 'data') else ground_truth
|
|
167
|
+
pred_data = prediction.data if hasattr(prediction, 'data') else prediction
|
|
168
|
+
|
|
169
|
+
# Move to CPU if needed
|
|
170
|
+
if hasattr(img_data, 'cpu'): img_data = img_data.cpu()
|
|
171
|
+
if hasattr(gt_data, 'cpu'): gt_data = gt_data.cpu()
|
|
172
|
+
if hasattr(pred_data, 'cpu'): pred_data = pred_data.cpu()
|
|
173
|
+
|
|
174
|
+
# Find optimal slice if not provided
|
|
175
|
+
if slice_index is None:
|
|
176
|
+
gt_np = gt_data[channel].numpy()
|
|
177
|
+
slice_index = find_max_slice(gt_np, anatomical_plane)
|
|
178
|
+
|
|
179
|
+
# Create figure
|
|
180
|
+
fig, axes = plt.subplots(1, 3, figsize=figsize)
|
|
181
|
+
|
|
182
|
+
# Get slices with proper aspect ratio using existing _get_slice helper
|
|
183
|
+
img_slice, img_aspect = _get_slice(img_data, channel, slice_index, anatomical_plane, voxel_size)
|
|
184
|
+
gt_slice, gt_aspect = _get_slice(gt_data, channel, slice_index, anatomical_plane, voxel_size)
|
|
185
|
+
pred_slice, pred_aspect = _get_slice(pred_data, channel, slice_index, anatomical_plane, voxel_size)
|
|
186
|
+
|
|
187
|
+
# Plot panels
|
|
188
|
+
axes[0].imshow(img_slice, cmap=cmap_img, aspect=img_aspect)
|
|
189
|
+
axes[0].set_title('Input Image')
|
|
190
|
+
axes[0].axis('off')
|
|
191
|
+
|
|
192
|
+
axes[1].imshow(gt_slice, cmap=cmap_mask, aspect=gt_aspect)
|
|
193
|
+
axes[1].set_title('Ground Truth')
|
|
194
|
+
axes[1].axis('off')
|
|
195
|
+
|
|
196
|
+
# Build prediction title
|
|
197
|
+
pred_title = 'Prediction'
|
|
198
|
+
if metric_value is not None:
|
|
199
|
+
pred_title = f'Prediction ({metric_name}: {metric_value:.4f})'
|
|
200
|
+
|
|
201
|
+
axes[2].imshow(pred_slice, cmap=cmap_mask, aspect=pred_aspect)
|
|
202
|
+
axes[2].set_title(pred_title)
|
|
203
|
+
axes[2].axis('off')
|
|
204
|
+
|
|
205
|
+
plt.tight_layout()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
fastMONAI/__init__.py,sha256=cID1jLnC_vj48GgMN6Yb1FA3JsQ95zNmCHmRYE8TFhY,22
|
|
2
|
+
fastMONAI/_modidx.py,sha256=9e2FCrV3l4HYPJ-qcHUVqI_Q6ps6UVxEEdD3OBCSwhw,66249
|
|
3
|
+
fastMONAI/dataset_info.py,sha256=hLNX0Jps8dPCbF6HYPO2PScZtn2qqAQBH07LtSubeFM,16306
|
|
4
|
+
fastMONAI/external_data.py,sha256=Ofa6RmSKYj8LKlzWqPGfg9lu9lTjBmolJTo1zVgTe6g,12263
|
|
5
|
+
fastMONAI/research_utils.py,sha256=LZu62g8BQAVYS4dD7qDsKHJXZnDd1uLkJ6LoaMDhUhk,590
|
|
6
|
+
fastMONAI/utils.py,sha256=8avga5wIGK4IlJ04SrN_Ba5STkBSuEA5G06EvdDHNBs,30493
|
|
7
|
+
fastMONAI/vision_all.py,sha256=L2JVYQq77X7Ko2SmzKUGAXwVjw898V_skGuQuYxjVd8,385
|
|
8
|
+
fastMONAI/vision_augmentation.py,sha256=nhFA-usts59AIYdDtzX8QJ1HrGY3bcEKu2koP3HZews,20604
|
|
9
|
+
fastMONAI/vision_core.py,sha256=xXGnutYD3sdWzpoMZHSfClUFmphsB7yFsDcY91Fa844,9539
|
|
10
|
+
fastMONAI/vision_data.py,sha256=_SgwSlNm4ZOooFnrp5vYnA7ZAweV60a3XaOnozDKm6w,11569
|
|
11
|
+
fastMONAI/vision_inference.py,sha256=fRPgIO-3XifBlCZY7qaucgymSLQQajcKvmZKWg0XfS4,7688
|
|
12
|
+
fastMONAI/vision_loss.py,sha256=NrHnk1yD4EBKsp6aippppXU4l-mwmsZOqE_bsZP3ZNI,3591
|
|
13
|
+
fastMONAI/vision_metrics.py,sha256=OED2ewWaZUtmkqc5CjmBWDboTVUlpsnsuFU-ZrIw4tI,18572
|
|
14
|
+
fastMONAI/vision_patch.py,sha256=SkEdOc_U2nrpjIVZ3wW4qwgciKnOCuzQXixRGyK3KaA,50118
|
|
15
|
+
fastMONAI/vision_plot.py,sha256=7HLkKQAwmwPvwrDxWlKP5IIHNNwWIrLkdsejqlOc27k,7282
|
|
16
|
+
fastmonai-0.6.0.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
|
|
17
|
+
fastmonai-0.6.0.dist-info/METADATA,sha256=vdTSIppLb0xQtNgaAtKQfyTDKH7qqVd2sZFsv1cKgoI,7075
|
|
18
|
+
fastmonai-0.6.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
19
|
+
fastmonai-0.6.0.dist-info/entry_points.txt,sha256=mVBsykSXMairzzk3hJaQ8c-UiwUZqGnn4aFZ24CpsBM,40
|
|
20
|
+
fastmonai-0.6.0.dist-info/top_level.txt,sha256=o8y7SWF9odtnIT3jvYtUn9okbJRlaAMCy7oPFCeQvQ8,10
|
|
21
|
+
fastmonai-0.6.0.dist-info/RECORD,,
|
fastmonai-0.5.4.dist-info/RECORD
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
fastMONAI/__init__.py,sha256=DITpct-LrdIsTgwx2NgH5Ghx5y8Xgz1YMimy1ZV5RTY,22
|
|
2
|
-
fastMONAI/_modidx.py,sha256=eEccmLX_gTevLLfGe2ywec46xRkZrduEndx1lDMEync,59028
|
|
3
|
-
fastMONAI/dataset_info.py,sha256=BzbTZAGTQ5idyXqf-tna84No5tu9Fjo2RJA6lTqhaW8,11043
|
|
4
|
-
fastMONAI/external_data.py,sha256=Ofa6RmSKYj8LKlzWqPGfg9lu9lTjBmolJTo1zVgTe6g,12263
|
|
5
|
-
fastMONAI/research_utils.py,sha256=LZu62g8BQAVYS4dD7qDsKHJXZnDd1uLkJ6LoaMDhUhk,590
|
|
6
|
-
fastMONAI/utils.py,sha256=6bUgyVzUenkAUtf9gxJXeRsz2xc8uzjqsvzU2UVDKNI,19944
|
|
7
|
-
fastMONAI/vision_all.py,sha256=L2JVYQq77X7Ko2SmzKUGAXwVjw898V_skGuQuYxjVd8,385
|
|
8
|
-
fastMONAI/vision_augmentation.py,sha256=EFEUkpU7xaGJGZd6iCqOfDe56zVrgAV8t_UC0iAAum0,15611
|
|
9
|
-
fastMONAI/vision_core.py,sha256=xXGnutYD3sdWzpoMZHSfClUFmphsB7yFsDcY91Fa844,9539
|
|
10
|
-
fastMONAI/vision_data.py,sha256=_SgwSlNm4ZOooFnrp5vYnA7ZAweV60a3XaOnozDKm6w,11569
|
|
11
|
-
fastMONAI/vision_inference.py,sha256=fRPgIO-3XifBlCZY7qaucgymSLQQajcKvmZKWg0XfS4,7688
|
|
12
|
-
fastMONAI/vision_loss.py,sha256=NrHnk1yD4EBKsp6aippppXU4l-mwmsZOqE_bsZP3ZNI,3591
|
|
13
|
-
fastMONAI/vision_metrics.py,sha256=OED2ewWaZUtmkqc5CjmBWDboTVUlpsnsuFU-ZrIw4tI,18572
|
|
14
|
-
fastMONAI/vision_patch.py,sha256=C-LQEYt1bYCdmWG9PZJdCqlB1ucqNEA40qVF5gDA_Bs,44927
|
|
15
|
-
fastMONAI/vision_plot.py,sha256=hdQQtS2fRdImKQABaUtK0vpmRw4hHEE8oZnsKAGy-0o,3808
|
|
16
|
-
fastmonai-0.5.4.dist-info/licenses/LICENSE,sha256=xV8xoN4VOL0uw9X8RSs2IMuD_Ss_a9yAbtGNeBWZwnw,11337
|
|
17
|
-
fastmonai-0.5.4.dist-info/METADATA,sha256=ssu77BruDlG-RdrjO2ee7x43WzbPN1WSytpmLgkd4YE,7075
|
|
18
|
-
fastmonai-0.5.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
19
|
-
fastmonai-0.5.4.dist-info/entry_points.txt,sha256=mVBsykSXMairzzk3hJaQ8c-UiwUZqGnn4aFZ24CpsBM,40
|
|
20
|
-
fastmonai-0.5.4.dist-info/top_level.txt,sha256=o8y7SWF9odtnIT3jvYtUn9okbJRlaAMCy7oPFCeQvQ8,10
|
|
21
|
-
fastmonai-0.5.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|