fastMONAI 0.5.4__tar.gz → 0.6.0__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.
- {fastmonai-0.5.4/fastMONAI.egg-info → fastmonai-0.6.0}/PKG-INFO +1 -1
- fastmonai-0.6.0/fastMONAI/__init__.py +1 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/_modidx.py +53 -1
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/dataset_info.py +144 -7
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/utils.py +296 -7
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_augmentation.py +137 -5
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_patch.py +157 -23
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_plot.py +89 -1
- {fastmonai-0.5.4 → fastmonai-0.6.0/fastMONAI.egg-info}/PKG-INFO +1 -1
- {fastmonai-0.5.4 → fastmonai-0.6.0}/settings.ini +1 -1
- fastmonai-0.5.4/fastMONAI/__init__.py +0 -1
- {fastmonai-0.5.4 → fastmonai-0.6.0}/CONTRIBUTING.md +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/LICENSE +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/MANIFEST.in +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/README.md +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/external_data.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/research_utils.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_all.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_core.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_data.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_inference.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_loss.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI/vision_metrics.py +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/SOURCES.txt +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/dependency_links.txt +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/entry_points.txt +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/not-zip-safe +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/requires.txt +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/fastMONAI.egg-info/top_level.txt +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/setup.cfg +0 -0
- {fastmonai-0.5.4 → fastmonai-0.6.0}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.0"
|
|
@@ -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__',
|
|
@@ -217,6 +239,16 @@ d = { 'settings': { 'branch': 'main',
|
|
|
217
239
|
'fastMONAI/vision_augmentation.py'),
|
|
218
240
|
'fastMONAI.vision_augmentation.ZNormalization.tio_transform': ( 'vision_augment.html#znormalization.tio_transform',
|
|
219
241
|
'fastMONAI/vision_augmentation.py'),
|
|
242
|
+
'fastMONAI.vision_augmentation._TioRandomCutout': ( 'vision_augment.html#_tiorandomcutout',
|
|
243
|
+
'fastMONAI/vision_augmentation.py'),
|
|
244
|
+
'fastMONAI.vision_augmentation._TioRandomCutout.__init__': ( 'vision_augment.html#_tiorandomcutout.__init__',
|
|
245
|
+
'fastMONAI/vision_augmentation.py'),
|
|
246
|
+
'fastMONAI.vision_augmentation._TioRandomCutout._apply_cutout': ( 'vision_augment.html#_tiorandomcutout._apply_cutout',
|
|
247
|
+
'fastMONAI/vision_augmentation.py'),
|
|
248
|
+
'fastMONAI.vision_augmentation._TioRandomCutout.apply_transform': ( 'vision_augment.html#_tiorandomcutout.apply_transform',
|
|
249
|
+
'fastMONAI/vision_augmentation.py'),
|
|
250
|
+
'fastMONAI.vision_augmentation._create_ellipsoid_mask': ( 'vision_augment.html#_create_ellipsoid_mask',
|
|
251
|
+
'fastMONAI/vision_augmentation.py'),
|
|
220
252
|
'fastMONAI.vision_augmentation.do_pad_or_crop': ( 'vision_augment.html#do_pad_or_crop',
|
|
221
253
|
'fastMONAI/vision_augmentation.py')},
|
|
222
254
|
'fastMONAI.vision_core': { 'fastMONAI.vision_core.MedBase': ('vision_core.html#medbase', 'fastMONAI/vision_core.py'),
|
|
@@ -353,12 +385,20 @@ d = { 'settings': { 'branch': 'main',
|
|
|
353
385
|
'fastMONAI/vision_metrics.py')},
|
|
354
386
|
'fastMONAI.vision_patch': { 'fastMONAI.vision_patch.MedPatchDataLoader': ( 'vision_patch.html#medpatchdataloader',
|
|
355
387
|
'fastMONAI/vision_patch.py'),
|
|
388
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__del__': ( 'vision_patch.html#medpatchdataloader.__del__',
|
|
389
|
+
'fastMONAI/vision_patch.py'),
|
|
390
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__enter__': ( 'vision_patch.html#medpatchdataloader.__enter__',
|
|
391
|
+
'fastMONAI/vision_patch.py'),
|
|
392
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.__exit__': ( 'vision_patch.html#medpatchdataloader.__exit__',
|
|
393
|
+
'fastMONAI/vision_patch.py'),
|
|
356
394
|
'fastMONAI.vision_patch.MedPatchDataLoader.__init__': ( 'vision_patch.html#medpatchdataloader.__init__',
|
|
357
395
|
'fastMONAI/vision_patch.py'),
|
|
358
396
|
'fastMONAI.vision_patch.MedPatchDataLoader.__iter__': ( 'vision_patch.html#medpatchdataloader.__iter__',
|
|
359
397
|
'fastMONAI/vision_patch.py'),
|
|
360
398
|
'fastMONAI.vision_patch.MedPatchDataLoader.__len__': ( 'vision_patch.html#medpatchdataloader.__len__',
|
|
361
399
|
'fastMONAI/vision_patch.py'),
|
|
400
|
+
'fastMONAI.vision_patch.MedPatchDataLoader.close': ( 'vision_patch.html#medpatchdataloader.close',
|
|
401
|
+
'fastMONAI/vision_patch.py'),
|
|
362
402
|
'fastMONAI.vision_patch.MedPatchDataLoader.dataset': ( 'vision_patch.html#medpatchdataloader.dataset',
|
|
363
403
|
'fastMONAI/vision_patch.py'),
|
|
364
404
|
'fastMONAI.vision_patch.MedPatchDataLoader.device': ( 'vision_patch.html#medpatchdataloader.device',
|
|
@@ -369,6 +409,12 @@ d = { 'settings': { 'branch': 'main',
|
|
|
369
409
|
'fastMONAI/vision_patch.py'),
|
|
370
410
|
'fastMONAI.vision_patch.MedPatchDataLoaders': ( 'vision_patch.html#medpatchdataloaders',
|
|
371
411
|
'fastMONAI/vision_patch.py'),
|
|
412
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__del__': ( 'vision_patch.html#medpatchdataloaders.__del__',
|
|
413
|
+
'fastMONAI/vision_patch.py'),
|
|
414
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__enter__': ( 'vision_patch.html#medpatchdataloaders.__enter__',
|
|
415
|
+
'fastMONAI/vision_patch.py'),
|
|
416
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.__exit__': ( 'vision_patch.html#medpatchdataloaders.__exit__',
|
|
417
|
+
'fastMONAI/vision_patch.py'),
|
|
372
418
|
'fastMONAI.vision_patch.MedPatchDataLoaders.__getitem__': ( 'vision_patch.html#medpatchdataloaders.__getitem__',
|
|
373
419
|
'fastMONAI/vision_patch.py'),
|
|
374
420
|
'fastMONAI.vision_patch.MedPatchDataLoaders.__init__': ( 'vision_patch.html#medpatchdataloaders.__init__',
|
|
@@ -381,6 +427,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
381
427
|
'fastMONAI/vision_patch.py'),
|
|
382
428
|
'fastMONAI.vision_patch.MedPatchDataLoaders.bs': ( 'vision_patch.html#medpatchdataloaders.bs',
|
|
383
429
|
'fastMONAI/vision_patch.py'),
|
|
430
|
+
'fastMONAI.vision_patch.MedPatchDataLoaders.close': ( 'vision_patch.html#medpatchdataloaders.close',
|
|
431
|
+
'fastMONAI/vision_patch.py'),
|
|
384
432
|
'fastMONAI.vision_patch.MedPatchDataLoaders.cpu': ( 'vision_patch.html#medpatchdataloaders.cpu',
|
|
385
433
|
'fastMONAI/vision_patch.py'),
|
|
386
434
|
'fastMONAI.vision_patch.MedPatchDataLoaders.cuda': ( 'vision_patch.html#medpatchdataloaders.cuda',
|
|
@@ -411,6 +459,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
411
459
|
'fastMONAI/vision_patch.py'),
|
|
412
460
|
'fastMONAI.vision_patch.PatchConfig.__post_init__': ( 'vision_patch.html#patchconfig.__post_init__',
|
|
413
461
|
'fastMONAI/vision_patch.py'),
|
|
462
|
+
'fastMONAI.vision_patch.PatchConfig.from_dataset': ( 'vision_patch.html#patchconfig.from_dataset',
|
|
463
|
+
'fastMONAI/vision_patch.py'),
|
|
414
464
|
'fastMONAI.vision_patch.PatchInferenceEngine': ( 'vision_patch.html#patchinferenceengine',
|
|
415
465
|
'fastMONAI/vision_patch.py'),
|
|
416
466
|
'fastMONAI.vision_patch.PatchInferenceEngine.__init__': ( 'vision_patch.html#patchinferenceengine.__init__',
|
|
@@ -441,5 +491,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
441
491
|
'fastMONAI.vision_plot.find_max_slice': ( 'vision_plot.html#find_max_slice',
|
|
442
492
|
'fastMONAI/vision_plot.py'),
|
|
443
493
|
'fastMONAI.vision_plot.show_med_img': ('vision_plot.html#show_med_img', 'fastMONAI/vision_plot.py'),
|
|
494
|
+
'fastMONAI.vision_plot.show_segmentation_comparison': ( 'vision_plot.html#show_segmentation_comparison',
|
|
495
|
+
'fastMONAI/vision_plot.py'),
|
|
444
496
|
'fastMONAI.vision_plot.validate_anatomical_plane': ( 'vision_plot.html#validate_anatomical_plane',
|
|
445
497
|
'fastMONAI/vision_plot.py')}}}
|
|
@@ -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
|
|