def filter_center(data, size=3, no_data_val=None, func=np.nanmean,
mask_no_data=False):
"""
Parameters
----------
data: input data
size: odd number uniform filtering kernel size
no_data_val: value in matrix that is treated as no data value
func: function to use, choose from np.nanmean/median/max/min etc.
mask_no_data: bool, if True will keep the original no data pixel intact
Returns: nanmean of the matrix A filtered by a uniform kernel of size=size
-------
Adapted from: http://stackoverflow.com/questions/23829097/python-numpy-fastest-method-for-2d-kernel-rank-filtering-on-masked-arrays-and-o?rq=1
Notes
-----
This function `centers` the kernel at the target pixel.
This is slightly different from scipy.ndimage.uniform_filter application.
In scipy.ndimage.uniform_filter, a convolution approach is implemented.
An equivalent is scipy.ndimage.uniform_filter like convolution approach
with no_data_val/nan handling can be found in
filter_broadcast_uniform_filter in this module.
Change function to nanmedian, nanmax, nanmin as required.
"""
assert size % 2 == 1, 'Please supply an odd size'
rows, cols = data.shape
padded_data = np.empty(shape=(rows + size-1,
cols + size-1),
dtype=data.dtype)
padded_data[:] = np.nan
rows_pad, cols_pad = padded_data.shape
if no_data_val is not None:
mask = data == no_data_val
data[mask] = np.nan
padded_data[size//2:rows_pad - size//2,
size//2: cols_pad - size//2] = data.copy()
row, col = data.shape
stride_data = as_strided(padded_data, (row, col, size, size),
padded_data.strides+padded_data.strides)
stride_data = stride_data.copy().reshape((row, col, size**2))
avg = func(stride_data, axis=2)
avg[np.isnan(avg)] = no_data_val
if mask_no_data:
avg[mask] = no_data_val
return avg
评论列表
文章目录