22
22
import torch
23
23
24
24
from monai .config import DtypeLike , KeysCollection
25
+ from monai .data .utils import get_random_patch , get_valid_patch_size
25
26
from monai .transforms .intensity .array import (
26
27
AdjustContrast ,
27
28
GaussianSharpen ,
41
42
ThresholdIntensity ,
42
43
)
43
44
from monai .transforms .transform import MapTransform , RandomizableTransform
44
- from monai .utils import dtype_torch_to_numpy , ensure_tuple_rep , ensure_tuple_size
45
+ from monai .utils import dtype_torch_to_numpy , ensure_tuple_rep , ensure_tuple_size , fall_back_tuple
45
46
46
47
__all__ = [
47
48
"RandGaussianNoised" ,
69
70
"KSpaceSpikeNoised" ,
70
71
"RandKSpaceSpikeNoised" ,
71
72
"RandHistogramShiftd" ,
73
+ "RandCoarseDropoutd" ,
72
74
"RandGaussianNoiseD" ,
73
75
"RandGaussianNoiseDict" ,
74
76
"ShiftIntensityD" ,
117
119
"RandHistogramShiftDict" ,
118
120
"RandRicianNoiseD" ,
119
121
"RandRicianNoiseDict" ,
122
+ "RandCoarseDropoutD" ,
123
+ "RandCoarseDropoutDict" ,
120
124
]
121
125
122
126
123
127
class RandGaussianNoised (RandomizableTransform , MapTransform ):
124
128
"""
125
129
Dictionary-based version :py:class:`monai.transforms.RandGaussianNoise`.
126
- Add Gaussian noise to image. This transform assumes all the expected fields have same shape.
130
+ Add Gaussian noise to image. This transform assumes all the expected fields have same shape, if want to add
131
+ different noise for every field, please use this transform separately.
127
132
128
133
Args:
129
134
keys: keys of the corresponding items to be transformed.
@@ -172,7 +177,8 @@ def __call__(self, data: Mapping[Hashable, np.ndarray]) -> Dict[Hashable, np.nda
172
177
class RandRicianNoised (RandomizableTransform , MapTransform ):
173
178
"""
174
179
Dictionary-based version :py:class:`monai.transforms.RandRicianNoise`.
175
- Add Rician noise to image. This transform assumes all the expected fields have same shape.
180
+ Add Rician noise to image. This transform assumes all the expected fields have same shape, if want to add
181
+ different noise for every field, please use this transform separately.
176
182
177
183
Args:
178
184
keys: Keys of the corresponding items to be transformed.
@@ -1324,6 +1330,78 @@ def _to_numpy(self, d: Union[torch.Tensor, np.ndarray]) -> np.ndarray:
1324
1330
return d_numpy
1325
1331
1326
1332
1333
+ class RandCoarseDropoutd (RandomizableTransform , MapTransform ):
1334
+ """
1335
+ Dictionary-based wrapper of :py:class:`monai.transforms.RandCoarseDropout`.
1336
+ Expect all the data specified by `keys` have same spatial shape and will randomly dropout the same regions
1337
+ for every key, if want to dropout differently for every key, please use this transform separately.
1338
+
1339
+ Args:
1340
+ keys: keys of the corresponding items to be transformed.
1341
+ See also: :py:class:`monai.transforms.compose.MapTransform`
1342
+ holes: number of regions to dropout, if `max_holes` is not None, use this arg as the minimum number to
1343
+ randomly select the expected number of regions.
1344
+ spatial_size: spatial size of the regions to dropout, if `max_spatial_size` is not None, use this arg
1345
+ as the minimum spatial size to randomly select size for every region.
1346
+ if some components of the `spatial_size` are non-positive values, the transform will use the
1347
+ corresponding components of input img size. For example, `spatial_size=(32, -1)` will be adapted
1348
+ to `(32, 64)` if the second spatial dimension size of img is `64`.
1349
+ fill_value: target value to fill the dropout regions.
1350
+ max_holes: if not None, define the maximum number to randomly select the expected number of regions.
1351
+ max_spatial_size: if not None, define the maximum spatial size to randomly select size for every region.
1352
+ if some components of the `max_spatial_size` are non-positive values, the transform will use the
1353
+ corresponding components of input img size. For example, `max_spatial_size=(32, -1)` will be adapted
1354
+ to `(32, 64)` if the second spatial dimension size of img is `64`.
1355
+ prob: probability of applying the transform.
1356
+ allow_missing_keys: don't raise exception if key is missing.
1357
+
1358
+ """
1359
+
1360
+ def __init__ (
1361
+ self ,
1362
+ keys : KeysCollection ,
1363
+ holes : int ,
1364
+ spatial_size : Union [Sequence [int ], int ],
1365
+ fill_value : Union [float , int ] = 0 ,
1366
+ max_holes : Optional [int ] = None ,
1367
+ max_spatial_size : Optional [Union [Sequence [int ], int ]] = None ,
1368
+ prob : float = 0.1 ,
1369
+ allow_missing_keys : bool = False ,
1370
+ ):
1371
+ MapTransform .__init__ (self , keys , allow_missing_keys )
1372
+ RandomizableTransform .__init__ (self , prob )
1373
+ if holes < 1 :
1374
+ raise ValueError ("number of holes must be greater than 0." )
1375
+ self .holes = holes
1376
+ self .spatial_size = spatial_size
1377
+ self .fill_value = fill_value
1378
+ self .max_holes = max_holes
1379
+ self .max_spatial_size = max_spatial_size
1380
+ self .hole_coords : List = []
1381
+
1382
+ def randomize (self , img_size : Sequence [int ]) -> None :
1383
+ super ().randomize (None )
1384
+ size = fall_back_tuple (self .spatial_size , img_size )
1385
+ self .hole_coords = [] # clear previously computed coords
1386
+ num_holes = self .holes if self .max_holes is None else self .R .randint (self .holes , self .max_holes + 1 )
1387
+ for _ in range (num_holes ):
1388
+ if self .max_spatial_size is not None :
1389
+ max_size = fall_back_tuple (self .max_spatial_size , img_size )
1390
+ size = tuple (self .R .randint (low = size [i ], high = max_size [i ] + 1 ) for i in range (len (img_size )))
1391
+ valid_size = get_valid_patch_size (img_size , size )
1392
+ self .hole_coords .append ((slice (None ),) + get_random_patch (img_size , valid_size , self .R ))
1393
+
1394
+ def __call__ (self , data ):
1395
+ d = dict (data )
1396
+ # expect all the specified keys have same spatial shape
1397
+ self .randomize (d [self .keys [0 ]].shape [1 :])
1398
+ if self ._do_transform :
1399
+ for key in self .key_iterator (d ):
1400
+ for h in self .hole_coords :
1401
+ d [key ][h ] = self .fill_value
1402
+ return d
1403
+
1404
+
1327
1405
RandGaussianNoiseD = RandGaussianNoiseDict = RandGaussianNoised
1328
1406
RandRicianNoiseD = RandRicianNoiseDict = RandRicianNoised
1329
1407
ShiftIntensityD = ShiftIntensityDict = ShiftIntensityd
@@ -1349,3 +1427,4 @@ def _to_numpy(self, d: Union[torch.Tensor, np.ndarray]) -> np.ndarray:
1349
1427
GibbsNoiseD = GibbsNoiseDict = GibbsNoised
1350
1428
KSpaceSpikeNoiseD = KSpaceSpikeNoiseDict = KSpaceSpikeNoised
1351
1429
RandKSpaceSpikeNoiseD = RandKSpaceSpikeNoiseDict = RandKSpaceSpikeNoised
1430
+ RandCoarseDropoutD = RandCoarseDropoutDict = RandCoarseDropoutd
0 commit comments