@@ -44,9 +44,10 @@ class Stack(object):
44
44
'max' - maximum stack
45
45
'mean' - average stack
46
46
'median' - median stack
47
+ 'sigma' - kappa-sigma stack
47
48
'''
48
49
49
- def __init__ (self , mode , num , nprocs = 1 ):
50
+ def __init__ (self , mode , num , nprocs = 1 , kwargs = None ):
50
51
LOGGER .debug ("Initializing %s stack for %d images." ,
51
52
mode , num )
52
53
self .stack = None
@@ -58,14 +59,15 @@ def __init__(self, mode, num, nprocs=1):
58
59
'calc' : None },
59
60
'mean' : {'update' : self ._update_mean ,
60
61
'calc' : None },
61
- # 'sigma': {'update': self._update_deep,
62
- # 'calc': self._calculate_sigma},
62
+ 'sigma' : {'update' : self ._update_deep ,
63
+ 'calc' : self ._calculate_sigma },
63
64
'median' : {'update' : self ._update_deep ,
64
65
'calc' : self ._calculate_median }}
65
66
self ._update_func = self ._mode_functions [mode ]['update' ]
66
67
self ._calculate_func = self ._mode_functions [mode ]['calc' ]
67
68
self .num = num
68
69
self ._num = 0
70
+ self ._kwargs = kwargs
69
71
70
72
def add_image (self , img ):
71
73
'''Add a frame to the stack.
@@ -178,4 +180,48 @@ def _calculate_sigma(self):
178
180
'''Calculate the sigma-reject average of the stack and return
179
181
the result as Image(dtype=uint16).
180
182
'''
181
- LOGGER .error ("Sigma stack not implemented." )
183
+ shape = self .stack ['R' ].shape
184
+ img = np .zeros ((shape [0 ], shape [1 ], 3 ), dtype = self .stack ['R' ].dtype )
185
+
186
+ try :
187
+ kappa = self ._kwargs ["kappa" ]
188
+ except (TypeError , KeyError ):
189
+ kappa = 2
190
+ try :
191
+ max_iters = self ._kwargs ["max_iters" ]
192
+ except (TypeError , KeyError ):
193
+ max_iters = self ._num / 4
194
+
195
+ LOGGER .info ("Calculating Sigma-Kappa average." )
196
+
197
+ img [:, :, 0 ] = _sigma_worker (self .stack ['R' ], kappa , max_iters )
198
+ img [:, :, 1 ] = _sigma_worker (self .stack ['G' ], kappa , max_iters )
199
+ img [:, :, 2 ] = _sigma_worker (self .stack ['B' ], kappa , max_iters )
200
+
201
+ return Image (img = img , nprocs = self .nprocs )
202
+
203
+ def _sigma_worker (data , kappa , max_iters ):
204
+ '''Calculate kappa-sigma mean of the data.'''
205
+
206
+ shape = data .shape
207
+ tile_shape = (shape [- 1 ], 1 )
208
+ data_out = np .empty ((shape [0 ], shape [1 ]), dtype = STACK_DTYPE ) # data.dtype)
209
+
210
+ for i in range (shape [0 ]):
211
+ num_it = 0
212
+ row = np .ma .masked_equal (data [i , :, :], 0 ).T
213
+ while True :
214
+ avgs = np .mean (row , 0 )
215
+ diffs = np .abs (np .tile (avgs , tile_shape ) - row )
216
+ stds = np .std (row , 0 )
217
+ idxs = diffs > kappa * np .tile (stds , tile_shape )
218
+ num_it += 1
219
+ if np .any (idxs ):
220
+ row = np .ma .masked_where (idxs , row )
221
+ else :
222
+ break
223
+ if num_it >= max_iters :
224
+ break
225
+ data_out [i , :] = np .mean (row , 0 )
226
+
227
+ return data_out
0 commit comments