fastMONAI 0.5.4__py3-none-any.whl → 0.6.1__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 +61 -1
- fastMONAI/dataset_info.py +144 -7
- fastMONAI/utils.py +296 -7
- fastMONAI/vision_augmentation.py +328 -34
- fastMONAI/vision_patch.py +175 -23
- fastMONAI/vision_plot.py +89 -1
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.1.dist-info}/METADATA +1 -1
- fastmonai-0.6.1.dist-info/RECORD +21 -0
- fastmonai-0.5.4.dist-info/RECORD +0 -21
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.1.dist-info}/WHEEL +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.1.dist-info}/entry_points.txt +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.1.dist-info}/licenses/LICENSE +0 -0
- {fastmonai-0.5.4.dist-info → fastmonai-0.6.1.dist-info}/top_level.txt +0 -0
fastMONAI/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.6.1"
|
fastMONAI/_modidx.py
CHANGED
|
@@ -16,6 +16,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
16
16
|
'fastMONAI/dataset_info.py'),
|
|
17
17
|
'fastMONAI.dataset_info.MedDataset.calculate_target_size': ( 'dataset_info.html#meddataset.calculate_target_size',
|
|
18
18
|
'fastMONAI/dataset_info.py'),
|
|
19
|
+
'fastMONAI.dataset_info.MedDataset.get_size_statistics': ( 'dataset_info.html#meddataset.get_size_statistics',
|
|
20
|
+
'fastMONAI/dataset_info.py'),
|
|
19
21
|
'fastMONAI.dataset_info.MedDataset.get_suggestion': ( 'dataset_info.html#meddataset.get_suggestion',
|
|
20
22
|
'fastMONAI/dataset_info.py'),
|
|
21
23
|
'fastMONAI.dataset_info.MedDataset.get_volume_summary': ( 'dataset_info.html#meddataset.get_volume_summary',
|
|
@@ -25,7 +27,9 @@ d = { 'settings': { 'branch': 'main',
|
|
|
25
27
|
'fastMONAI.dataset_info.MedDataset.visualize_cases': ( 'dataset_info.html#meddataset.visualize_cases',
|
|
26
28
|
'fastMONAI/dataset_info.py'),
|
|
27
29
|
'fastMONAI.dataset_info.get_class_weights': ( 'dataset_info.html#get_class_weights',
|
|
28
|
-
'fastMONAI/dataset_info.py')
|
|
30
|
+
'fastMONAI/dataset_info.py'),
|
|
31
|
+
'fastMONAI.dataset_info.suggest_patch_size': ( 'dataset_info.html#suggest_patch_size',
|
|
32
|
+
'fastMONAI/dataset_info.py')},
|
|
29
33
|
'fastMONAI.external_data': { 'fastMONAI.external_data.MURLs': ('external_data.html#murls', 'fastMONAI/external_data.py'),
|
|
30
34
|
'fastMONAI.external_data._create_nodule_df': ( 'external_data.html#_create_nodule_df',
|
|
31
35
|
'fastMONAI/external_data.py'),
|
|
@@ -87,6 +91,14 @@ d = { 'settings': { 'branch': 'main',
|
|
|
87
91
|
'fastMONAI/utils.py'),
|
|
88
92
|
'fastMONAI.utils.ModelTrackingCallback.extract_all_params': ( 'utils.html#modeltrackingcallback.extract_all_params',
|
|
89
93
|
'fastMONAI/utils.py'),
|
|
94
|
+
'fastMONAI.utils._detect_patch_workflow': ('utils.html#_detect_patch_workflow', 'fastMONAI/utils.py'),
|
|
95
|
+
'fastMONAI.utils._extract_loss_name': ('utils.html#_extract_loss_name', 'fastMONAI/utils.py'),
|
|
96
|
+
'fastMONAI.utils._extract_model_name': ('utils.html#_extract_model_name', 'fastMONAI/utils.py'),
|
|
97
|
+
'fastMONAI.utils._extract_patch_config': ('utils.html#_extract_patch_config', 'fastMONAI/utils.py'),
|
|
98
|
+
'fastMONAI.utils._extract_size_from_transforms': ( 'utils.html#_extract_size_from_transforms',
|
|
99
|
+
'fastMONAI/utils.py'),
|
|
100
|
+
'fastMONAI.utils._extract_standard_config': ('utils.html#_extract_standard_config', 'fastMONAI/utils.py'),
|
|
101
|
+
'fastMONAI.utils.create_mlflow_callback': ('utils.html#create_mlflow_callback', 'fastMONAI/utils.py'),
|
|
90
102
|
'fastMONAI.utils.load_patch_variables': ('utils.html#load_patch_variables', 'fastMONAI/utils.py'),
|
|
91
103
|
'fastMONAI.utils.load_variables': ('utils.html#load_variables', 'fastMONAI/utils.py'),
|
|
92
104
|
'fastMONAI.utils.print_colab_gpu_info': ('utils.html#print_colab_gpu_info', 'fastMONAI/utils.py'),
|
|
@@ -147,6 +159,16 @@ d = { 'settings': { 'branch': 'main',
|
|
|
147
159
|
'fastMONAI/vision_augmentation.py'),
|
|
148
160
|
'fastMONAI.vision_augmentation.RandomBlur.tio_transform': ( 'vision_augment.html#randomblur.tio_transform',
|
|
149
161
|
'fastMONAI/vision_augmentation.py'),
|
|
162
|
+
'fastMONAI.vision_augmentation.RandomCutout': ( 'vision_augment.html#randomcutout',
|
|
163
|
+
'fastMONAI/vision_augmentation.py'),
|
|
164
|
+
'fastMONAI.vision_augmentation.RandomCutout.__init__': ( 'vision_augment.html#randomcutout.__init__',
|
|
165
|
+
'fastMONAI/vision_augmentation.py'),
|
|
166
|
+
'fastMONAI.vision_augmentation.RandomCutout._get_fill_value': ( 'vision_augment.html#randomcutout._get_fill_value',
|
|
167
|
+
'fastMONAI/vision_augmentation.py'),
|
|
168
|
+
'fastMONAI.vision_augmentation.RandomCutout.encodes': ( 'vision_augment.html#randomcutout.encodes',
|
|
169
|
+
'fastMONAI/vision_augmentation.py'),
|
|
170
|
+
'fastMONAI.vision_augmentation.RandomCutout.tio_transform': ( 'vision_augment.html#randomcutout.tio_transform',
|
|
171
|
+
'fastMONAI/vision_augmentation.py'),
|
|
150
172
|
'fastMONAI.vision_augmentation.RandomElasticDeformation': ( 'vision_augment.html#randomelasticdeformation',
|
|
151
173
|
'fastMONAI/vision_augmentation.py'),
|
|
152
174
|
'fastMONAI.vision_augmentation.RandomElasticDeformation.__init__': ( 'vision_augment.html#randomelasticdeformation.__init__',
|
|
@@ -209,6 +231,14 @@ d = { 'settings': { 'branch': 'main',
|
|
|
209
231
|
'fastMONAI/vision_augmentation.py'),
|
|
210
232
|
'fastMONAI.vision_augmentation.RescaleIntensity.tio_transform': ( 'vision_augment.html#rescaleintensity.tio_transform',
|
|
211
233
|
'fastMONAI/vision_augmentation.py'),
|
|
234
|
+
'fastMONAI.vision_augmentation.SpatialPad': ( 'vision_augment.html#spatialpad',
|
|
235
|
+
'fastMONAI/vision_augmentation.py'),
|
|
236
|
+
'fastMONAI.vision_augmentation.SpatialPad.__init__': ( 'vision_augment.html#spatialpad.__init__',
|
|
237
|
+
'fastMONAI/vision_augmentation.py'),
|
|
238
|
+
'fastMONAI.vision_augmentation.SpatialPad.encodes': ( 'vision_augment.html#spatialpad.encodes',
|
|
239
|
+
'fastMONAI/vision_augmentation.py'),
|
|
240
|
+
'fastMONAI.vision_augmentation.SpatialPad.tio_transform': ( 'vision_augment.html#spatialpad.tio_transform',
|
|
241
|
+
'fastMONAI/vision_augmentation.py'),
|
|
212
242
|
'fastMONAI.vision_augmentation.ZNormalization': ( 'vision_augment.html#znormalization',
|
|
213
243
|
'fastMONAI/vision_augmentation.py'),
|
|
214
244
|
'fastMONAI.vision_augmentation.ZNormalization.__init__': ( 'vision_augment.html#znormalization.__init__',
|
|
@@ -217,6 +247,16 @@ d = { 'settings': { 'branch': 'main',
|
|
|
217
247
|
'fastMONAI/vision_augmentation.py'),
|
|
218
248
|
'fastMONAI.vision_augmentation.ZNormalization.tio_transform': ( 'vision_augment.html#znormalization.tio_transform',
|
|
219
249
|
'fastMONAI/vision_augmentation.py'),
|
|
250
|
+
'fastMONAI.vision_augmentation._TioRandomCutout': ( 'vision_augment.html#_tiorandomcutout',
|
|
251
|
+
'fastMONAI/vision_augmentation.py'),
|
|
252
|
+
'fastMONAI.vision_augmentation._TioRandomCutout.__init__': ( 'vision_augment.html#_tiorandomcutout.__init__',
|
|
253
|
+
'fastMONAI/vision_augmentation.py'),
|
|
254
|
+
'fastMONAI.vision_augmentation._TioRandomCutout._apply_cutout': ( 'vision_augment.html#_tiorandomcutout._apply_cutout',
|
|
255
|
+
'fastMONAI/vision_augmentation.py'),
|
|
256
|
+
'fastMONAI.vision_augmentation._TioRandomCutout.apply_transform': ( 'vision_augment.html#_tiorandomcutout.apply_transform',
|
|
257
|
+
'fastMONAI/vision_augmentation.py'),
|
|
258
|
+
'fastMONAI.vision_augmentation._create_ellipsoid_mask': ( 'vision_augment.html#_create_ellipsoid_mask',
|
|
259
|
+
'fastMONAI/vision_augmentation.py'),
|
|
220
260
|
'fastMONAI.vision_augmentation.do_pad_or_crop': ( 'vision_augment.html#do_pad_or_crop',
|
|
221
261
|
'fastMONAI/vision_augmentation.py')},
|
|
222
262
|
'fastMONAI.vision_core': { 'fastMONAI.vision_core.MedBase': ('vision_core.html#medbase', 'fastMONAI/vision_core.py'),
|
|
@@ -353,12 +393,20 @@ d = { 'settings': { 'branch': 'main',
|
|
|
353
393
|
'fastMONAI/vision_metrics.py')},
|
|
354
394
|
'fastMONAI.vision_patch': { 'fastMONAI.vision_patch.MedPatchDataLoader': ( 'vision_patch.html#medpatchdataloader',
|
|
355
395
|
'fastMONAI/vision_patch.py'),
|
|
396
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__del__': ( 'vision_patch.html#medpatchdataloader.__del__',
|
|
397
|
+
'fastMONAI/vision_patch.py'),
|
|
398
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__enter__': ( 'vision_patch.html#medpatchdataloader.__enter__',
|
|
399
|
+
'fastMONAI/vision_patch.py'),
|
|
400
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__exit__': ( 'vision_patch.html#medpatchdataloader.__exit__',
|
|
401
|
+
'fastMONAI/vision_patch.py'),
|
|
356
402
|
'fastMONAI.vision_patch.MedPatchDataLoader.__init__': ( 'vision_patch.html#medpatchdataloader.__init__',
|
|
357
403
|
'fastMONAI/vision_patch.py'),
|
|
358
404
|
'fastMONAI.vision_patch.MedPatchDataLoader.__iter__': ( 'vision_patch.html#medpatchdataloader.__iter__',
|
|
359
405
|
'fastMONAI/vision_patch.py'),
|
|
360
406
|
'fastMONAI.vision_patch.MedPatchDataLoader.__len__': ( 'vision_patch.html#medpatchdataloader.__len__',
|
|
361
407
|
'fastMONAI/vision_patch.py'),
|
|
408
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.close': ( 'vision_patch.html#medpatchdataloader.close',
|
|
409
|
+
'fastMONAI/vision_patch.py'),
|
|
362
410
|
'fastMONAI.vision_patch.MedPatchDataLoader.dataset': ( 'vision_patch.html#medpatchdataloader.dataset',
|
|
363
411
|
'fastMONAI/vision_patch.py'),
|
|
364
412
|
'fastMONAI.vision_patch.MedPatchDataLoader.device': ( 'vision_patch.html#medpatchdataloader.device',
|
|
@@ -369,6 +417,12 @@ d = { 'settings': { 'branch': 'main',
|
|
|
369
417
|
'fastMONAI/vision_patch.py'),
|
|
370
418
|
'fastMONAI.vision_patch.MedPatchDataLoaders': ( 'vision_patch.html#medpatchdataloaders',
|
|
371
419
|
'fastMONAI/vision_patch.py'),
|
|
420
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__del__': ( 'vision_patch.html#medpatchdataloaders.__del__',
|
|
421
|
+
'fastMONAI/vision_patch.py'),
|
|
422
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__enter__': ( 'vision_patch.html#medpatchdataloaders.__enter__',
|
|
423
|
+
'fastMONAI/vision_patch.py'),
|
|
424
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__exit__': ( 'vision_patch.html#medpatchdataloaders.__exit__',
|
|
425
|
+
'fastMONAI/vision_patch.py'),
|
|
372
426
|
'fastMONAI.vision_patch.MedPatchDataLoaders.__getitem__': ( 'vision_patch.html#medpatchdataloaders.__getitem__',
|
|
373
427
|
'fastMONAI/vision_patch.py'),
|
|
374
428
|
'fastMONAI.vision_patch.MedPatchDataLoaders.__init__': ( 'vision_patch.html#medpatchdataloaders.__init__',
|
|
@@ -381,6 +435,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
381
435
|
'fastMONAI/vision_patch.py'),
|
|
382
436
|
'fastMONAI.vision_patch.MedPatchDataLoaders.bs': ( 'vision_patch.html#medpatchdataloaders.bs',
|
|
383
437
|
'fastMONAI/vision_patch.py'),
|
|
438
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.close': ( 'vision_patch.html#medpatchdataloaders.close',
|
|
439
|
+
'fastMONAI/vision_patch.py'),
|
|
384
440
|
'fastMONAI.vision_patch.MedPatchDataLoaders.cpu': ( 'vision_patch.html#medpatchdataloaders.cpu',
|
|
385
441
|
'fastMONAI/vision_patch.py'),
|
|
386
442
|
'fastMONAI.vision_patch.MedPatchDataLoaders.cuda': ( 'vision_patch.html#medpatchdataloaders.cuda',
|
|
@@ -411,6 +467,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
411
467
|
'fastMONAI/vision_patch.py'),
|
|
412
468
|
'fastMONAI.vision_patch.PatchConfig.__post_init__': ( 'vision_patch.html#patchconfig.__post_init__',
|
|
413
469
|
'fastMONAI/vision_patch.py'),
|
|
470
|
+
'fastMONAI.vision_patch.PatchConfig.from_dataset': ( 'vision_patch.html#patchconfig.from_dataset',
|
|
471
|
+
'fastMONAI/vision_patch.py'),
|
|
414
472
|
'fastMONAI.vision_patch.PatchInferenceEngine': ( 'vision_patch.html#patchinferenceengine',
|
|
415
473
|
'fastMONAI/vision_patch.py'),
|
|
416
474
|
'fastMONAI.vision_patch.PatchInferenceEngine.__init__': ( 'vision_patch.html#patchinferenceengine.__init__',
|
|
@@ -441,5 +499,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
441
499
|
'fastMONAI.vision_plot.find_max_slice': ( 'vision_plot.html#find_max_slice',
|
|
442
500
|
'fastMONAI/vision_plot.py'),
|
|
443
501
|
'fastMONAI.vision_plot.show_med_img': ('vision_plot.html#show_med_img', 'fastMONAI/vision_plot.py'),
|
|
502
|
+
'fastMONAI.vision_plot.show_segmentation_comparison': ( 'vision_plot.html#show_segmentation_comparison',
|
|
503
|
+
'fastMONAI/vision_plot.py'),
|
|
444
504
|
'fastMONAI.vision_plot.validate_anatomical_plane': ( 'vision_plot.html#validate_anatomical_plane',
|
|
445
505
|
'fastMONAI/vision_plot.py')}}}
|
fastMONAI/dataset_info.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/08_dataset_info.ipynb.
|
|
2
2
|
|
|
3
3
|
# %% auto 0
|
|
4
|
-
__all__ = ['MedDataset', 'get_class_weights']
|
|
4
|
+
__all__ = ['MedDataset', 'suggest_patch_size', 'get_class_weights']
|
|
5
5
|
|
|
6
6
|
# %% ../nbs/08_dataset_info.ipynb 2
|
|
7
7
|
from .vision_core import *
|
|
@@ -16,11 +16,13 @@ import glob
|
|
|
16
16
|
import matplotlib.pyplot as plt
|
|
17
17
|
|
|
18
18
|
# %% ../nbs/08_dataset_info.ipynb 3
|
|
19
|
+
import warnings
|
|
20
|
+
|
|
19
21
|
class MedDataset:
|
|
20
22
|
"""A class to extract and present information about the dataset."""
|
|
21
23
|
|
|
22
24
|
def __init__(self, dataframe=None, image_col:str=None, mask_col:str="mask_path",
|
|
23
|
-
path=None, img_list=None, postfix:str='', apply_reorder:bool=
|
|
25
|
+
path=None, img_list=None, postfix:str='', apply_reorder:bool=True,
|
|
24
26
|
dtype:(MedImage, MedMask)=MedImage, max_workers:int=1):
|
|
25
27
|
"""Constructs MedDataset object.
|
|
26
28
|
|
|
@@ -92,14 +94,31 @@ class MedDataset:
|
|
|
92
94
|
example_path=('path', 'min'), total=('path', 'size')
|
|
93
95
|
).sort_values('total', ascending=False)
|
|
94
96
|
|
|
95
|
-
def get_suggestion(self):
|
|
97
|
+
def get_suggestion(self, include_patch_size: bool = False):
|
|
96
98
|
"""Returns suggested preprocessing parameters as a dictionary.
|
|
97
99
|
|
|
100
|
+
The returned target_spacing is derived from the mode (most common value)
|
|
101
|
+
of voxel spacings in the dataset.
|
|
102
|
+
|
|
103
|
+
Note:
|
|
104
|
+
apply_reorder is NOT included in the return value because it is not
|
|
105
|
+
data-derived. Access dataset.apply_reorder directly if needed.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
include_patch_size: If True, includes suggested patch_size for
|
|
109
|
+
patch-based training. Requires vision_patch module.
|
|
110
|
+
|
|
98
111
|
Returns:
|
|
99
|
-
dict: {'target_spacing': [voxel_0, voxel_1, voxel_2]
|
|
112
|
+
dict: {'target_spacing': [voxel_0, voxel_1, voxel_2]}
|
|
113
|
+
If include_patch_size=True, also includes 'patch_size': [dim_0, dim_1, dim_2]
|
|
100
114
|
"""
|
|
101
115
|
target_spacing = [float(self.df.voxel_0.mode()[0]), float(self.df.voxel_1.mode()[0]), float(self.df.voxel_2.mode()[0])]
|
|
102
|
-
|
|
116
|
+
result = {'target_spacing': target_spacing}
|
|
117
|
+
|
|
118
|
+
if include_patch_size:
|
|
119
|
+
result['patch_size'] = suggest_patch_size(self)
|
|
120
|
+
|
|
121
|
+
return result
|
|
103
122
|
|
|
104
123
|
def _get_data_info(self, fn: str):
|
|
105
124
|
"""Private method to collect information about an image file."""
|
|
@@ -133,6 +152,10 @@ class MedDataset:
|
|
|
133
152
|
def calculate_target_size(self, target_spacing: list = None) -> list:
|
|
134
153
|
"""Calculate the target image size for the dataset.
|
|
135
154
|
|
|
155
|
+
.. deprecated::
|
|
156
|
+
Use `get_size_statistics(target_spacing)['max']` instead for consistency
|
|
157
|
+
with other size statistics methods.
|
|
158
|
+
|
|
136
159
|
Args:
|
|
137
160
|
target_spacing: If provided, calculates size after resampling to this spacing.
|
|
138
161
|
If None, returns original dimensions.
|
|
@@ -140,6 +163,12 @@ class MedDataset:
|
|
|
140
163
|
Returns:
|
|
141
164
|
list: [dim_0, dim_1, dim_2] largest dimensions in dataset.
|
|
142
165
|
"""
|
|
166
|
+
warnings.warn(
|
|
167
|
+
"calculate_target_size() is deprecated. "
|
|
168
|
+
"Use get_size_statistics(target_spacing)['max'] instead.",
|
|
169
|
+
DeprecationWarning,
|
|
170
|
+
stacklevel=2
|
|
171
|
+
)
|
|
143
172
|
if target_spacing is not None:
|
|
144
173
|
org_voxels = self.df[["voxel_0", "voxel_1", 'voxel_2']].values
|
|
145
174
|
org_dims = self.df[["dim_0", "dim_1", 'dim_2']].values
|
|
@@ -153,6 +182,38 @@ class MedDataset:
|
|
|
153
182
|
|
|
154
183
|
return dims
|
|
155
184
|
|
|
185
|
+
def get_size_statistics(self, target_spacing: list = None) -> dict:
|
|
186
|
+
"""Calculate comprehensive size statistics for the dataset.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
target_spacing: If provided, calculates statistics after
|
|
190
|
+
simulating resampling to this spacing.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
dict with keys: 'median', 'min', 'max', 'std', 'percentile_10', 'percentile_90'
|
|
194
|
+
Each value is a list [dim_0, dim_1, dim_2].
|
|
195
|
+
"""
|
|
196
|
+
if len(self.df) == 0:
|
|
197
|
+
raise ValueError("Dataset is empty - cannot calculate statistics")
|
|
198
|
+
|
|
199
|
+
if target_spacing is not None:
|
|
200
|
+
# Simulate resampled dimensions
|
|
201
|
+
org_voxels = self.df[["voxel_0", "voxel_1", "voxel_2"]].values
|
|
202
|
+
org_dims = self.df[["dim_0", "dim_1", "dim_2"]].values
|
|
203
|
+
ratio = org_voxels / np.array(target_spacing)
|
|
204
|
+
dims = np.floor(org_dims * ratio)
|
|
205
|
+
else:
|
|
206
|
+
dims = self.df[["dim_0", "dim_1", "dim_2"]].values
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
'median': [float(np.median(dims[:, i])) for i in range(3)],
|
|
210
|
+
'min': [float(np.min(dims[:, i])) for i in range(3)],
|
|
211
|
+
'max': [float(np.max(dims[:, i])) for i in range(3)],
|
|
212
|
+
'std': [float(np.std(dims[:, i])) for i in range(3)],
|
|
213
|
+
'percentile_10': [float(np.percentile(dims[:, i], 10)) for i in range(3)],
|
|
214
|
+
'percentile_90': [float(np.percentile(dims[:, i], 90)) for i in range(3)],
|
|
215
|
+
}
|
|
216
|
+
|
|
156
217
|
def get_volume_summary(self):
|
|
157
218
|
"""Returns DataFrame with volume statistics for each label.
|
|
158
219
|
|
|
@@ -185,7 +246,7 @@ class MedDataset:
|
|
|
185
246
|
try:
|
|
186
247
|
# Create MedImage and MedMask with current preprocessing settings
|
|
187
248
|
suggestion = self.get_suggestion()
|
|
188
|
-
MedBase.item_preprocessing(target_spacing=suggestion['target_spacing'], apply_reorder=
|
|
249
|
+
MedBase.item_preprocessing(target_spacing=suggestion['target_spacing'], apply_reorder=self.apply_reorder)
|
|
189
250
|
|
|
190
251
|
img = MedImage.create(img_path)
|
|
191
252
|
mask = MedMask.create(mask_path)
|
|
@@ -250,7 +311,83 @@ class MedDataset:
|
|
|
250
311
|
self._visualize_single_case(img_path, mask_path, case_id, anatomical_plane, cmap, figsize)
|
|
251
312
|
print("-" * 60)
|
|
252
313
|
|
|
253
|
-
# %% ../nbs/08_dataset_info.ipynb
|
|
314
|
+
# %% ../nbs/08_dataset_info.ipynb 4
|
|
315
|
+
def suggest_patch_size(
|
|
316
|
+
dataset: MedDataset,
|
|
317
|
+
target_spacing: list = None,
|
|
318
|
+
min_patch_size: list = None,
|
|
319
|
+
max_patch_size: list = None,
|
|
320
|
+
divisor: int = 16
|
|
321
|
+
) -> list:
|
|
322
|
+
"""Suggest optimal patch size based on median image dimensions.
|
|
323
|
+
|
|
324
|
+
Algorithm:
|
|
325
|
+
1. Use median shape for robustness to outliers
|
|
326
|
+
2. Round down to nearest multiple of divisor (16 for 4+ UNet pooling layers)
|
|
327
|
+
3. Clamp to [min_patch_size, max_patch_size]
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
dataset: MedDataset instance with analyzed images.
|
|
331
|
+
target_spacing: Target voxel spacing [x, y, z]. If None, uses
|
|
332
|
+
dataset.get_suggestion()['target_spacing'].
|
|
333
|
+
min_patch_size: Minimum per dimension. Default [32, 32, 32].
|
|
334
|
+
max_patch_size: Maximum per dimension. Default [256, 256, 256].
|
|
335
|
+
divisor: Ensure divisibility (default 16 for UNet compatibility).
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
list: [patch_dim_0, patch_dim_1, patch_dim_2]
|
|
339
|
+
|
|
340
|
+
Example:
|
|
341
|
+
>>> from fastMONAI.dataset_info import MedDataset
|
|
342
|
+
>>> dataset = MedDataset(dataframe=df, mask_col='mask_path', dtype=MedMask)
|
|
343
|
+
>>>
|
|
344
|
+
>>> # Use recommended spacing
|
|
345
|
+
>>> patch_size = suggest_patch_size(dataset)
|
|
346
|
+
>>>
|
|
347
|
+
>>> # Use custom spacing
|
|
348
|
+
>>> patch_size = suggest_patch_size(dataset, target_spacing=[1.0, 1.0, 2.0])
|
|
349
|
+
"""
|
|
350
|
+
# Defaults
|
|
351
|
+
min_patch_size = min_patch_size or [32, 32, 32]
|
|
352
|
+
max_patch_size = max_patch_size or [256, 256, 256]
|
|
353
|
+
|
|
354
|
+
# Use explicit spacing or get from dataset suggestion
|
|
355
|
+
if target_spacing is None:
|
|
356
|
+
suggestion = dataset.get_suggestion()
|
|
357
|
+
target_spacing = suggestion['target_spacing']
|
|
358
|
+
|
|
359
|
+
# Get size statistics (resampled to target_spacing)
|
|
360
|
+
stats = dataset.get_size_statistics(target_spacing)
|
|
361
|
+
median_shape = stats['median']
|
|
362
|
+
|
|
363
|
+
# Handle single-image edge case
|
|
364
|
+
if len(dataset.df) == 1:
|
|
365
|
+
warnings.warn("Single image dataset - using image dimensions directly")
|
|
366
|
+
|
|
367
|
+
# Step 1: Round down to nearest divisor
|
|
368
|
+
def round_to_divisor(val, div):
|
|
369
|
+
"""Round down to nearest multiple of divisor."""
|
|
370
|
+
return max(div, int(val // div) * div)
|
|
371
|
+
|
|
372
|
+
patch_size = [round_to_divisor(dim, divisor) for dim in median_shape]
|
|
373
|
+
|
|
374
|
+
# Step 2: Clamp to bounds
|
|
375
|
+
patch_size = [
|
|
376
|
+
max(min_p, min(max_p, p))
|
|
377
|
+
for p, min_p, max_p in zip(patch_size, min_patch_size, max_patch_size)
|
|
378
|
+
]
|
|
379
|
+
|
|
380
|
+
# Edge case: image smaller than suggested patch
|
|
381
|
+
for i, (p, median_dim) in enumerate(zip(patch_size, median_shape)):
|
|
382
|
+
if median_dim < p:
|
|
383
|
+
warnings.warn(
|
|
384
|
+
f"Median dimension {i} ({median_dim:.0f}) smaller than suggested "
|
|
385
|
+
f"patch_size ({p}). Images will require padding."
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
return patch_size
|
|
389
|
+
|
|
390
|
+
# %% ../nbs/08_dataset_info.ipynb 6
|
|
254
391
|
def get_class_weights(labels: (np.array, list), class_weight: str = 'balanced') -> torch.Tensor:
|
|
255
392
|
"""Calculates and returns the class weights.
|
|
256
393
|
|