@@ -962,9 +962,8 @@ class AddNoiseInputSpec(TraitedSpec):
962
962
in_mask = File (exists = True , desc = ('input mask, voxels outside this mask '
963
963
'will be considered background' ))
964
964
snr = traits .Float (10.0 , desc = 'desired output SNR in dB' , usedefault = True )
965
- dist = traits .Enum ('normal' , usedefault = True , mandatory = True ,
966
- desc = ('desired noise distribution, currently '
967
- 'only normal is implemented' ))
965
+ dist = traits .Enum ('normal' , 'rician' , usedefault = True , mandatory = True ,
966
+ desc = ('desired noise distribution' ))
968
967
bg_dist = traits .Enum ('normal' , 'rayleigh' , usedefault = True , mandatory = True ,
969
968
desc = ('desired noise distribution, currently '
970
969
'only normal is implemented' ))
@@ -1032,23 +1031,37 @@ def gen_noise(self, image, mask=None, snr_db=10.0, dist='normal', bg_dist='norma
1032
1031
1033
1032
if mask is None :
1034
1033
mask = np .ones_like (image )
1034
+ else :
1035
+ mask [mask > 0 ] = 1
1036
+ mask [mask < 1 ] = 0
1037
+
1038
+ if mask .ndim < image .ndim :
1039
+ mask = np .rollaxis (np .array ([mask ]* image .shape [3 ]),0 , 4 )
1035
1040
1036
1041
signal = image [mask > 0 ].reshape (- 1 )
1037
- signal = signal - signal .mean ()
1038
- sigma_s = signal .var ()
1039
- sigma_n = sqrt ((sigma_s ** 2 )/ snr )
1040
1042
1041
1043
if dist == 'normal' :
1044
+ signal = signal - signal .mean ()
1045
+ sigma_n = sqrt (signal .var ()/ snr )
1042
1046
noise = np .random .normal (size = image .shape , scale = sigma_n )
1043
- else :
1044
- raise NotImplementedError ('Only normal distribution is supported' )
1045
1047
1046
- if np .any (mask == 0 ):
1047
- if bg_dist == 'rayleigh' :
1048
+ if (np .any (mask == 0 )) and (bg_dist == 'rayleigh' ):
1048
1049
bg_noise = np .random .rayleigh (size = image .shape , scale = sigma_n )
1049
1050
noise [mask == 0 ] = bg_noise [mask == 0 ]
1050
1051
1051
- im_noise = image + noise
1052
+ im_noise = image + noise
1053
+
1054
+ elif dist == 'rician' :
1055
+ sigma_n = signal .mean ()/ snr
1056
+ n_1 = np .random .normal (size = image .shape , scale = sigma_n )
1057
+ n_2 = np .random .normal (size = image .shape , scale = sigma_n )
1058
+ stde_1 = n_1 / sqrt (2.0 )
1059
+ stde_2 = n_2 / sqrt (2.0 )
1060
+ im_noise = np .sqrt ((image + stde_1 )** 2 + (stde_2 )** 2 )
1061
+ else :
1062
+ raise NotImplementedError (('Only normal and rician distributions '
1063
+ 'are supported' ))
1064
+
1052
1065
return im_noise
1053
1066
1054
1067
0 commit comments