Вот векторизованное решение. Однако вы можете найти более быстрое решение, обращая внимание на порядок памяти массива изображений:
from numpy.lib.stride_tricks import as_strided
img_padded = np.pad(img, 1, mode='constant')
sub_shape = (fsize, fsize)
view_shape = tuple(np.subtract(img_padded.shape, sub_shape) + 1) + sub_shape
sub_img = as_strided(img_padded, view_shape, img_padded.strides * 2)
sub_img = sub_img.reshape(img.shape + (fsize**2,))
result = np.median(sub_img, axis=2).astype(int)
Используйте функцию pad
для заполнения сначала, а затем as_strided
для получения sub_matrices и, наконец, применения median
к вашим шагам.
ОБНОВЛЕНИЕ : использование view_as_windows
, предложенного @Divakar в комментариях:
from skimage.util.shape import view_as_windows
img_padded = np.pad(img, 1, mode='constant')
sub_shape = (fsize, fsize)
view_shape = view_as_windows(img_padded, sub_shape, 1)
sub_img = view_shape.reshape(img.shape + (fsize**2,))
result = np.median(sub_img, axis=2).astype(int)
view_as_windows
также обеспечивает подобласти подматрицы к шагам.
образец изображения и вывод:
img:
[[ 1 2 3 4 5 6]
[ 7 8 9 10 11 12]
[13 14 15 16 17 18]
[19 20 21 22 23 24]]
median_filtered:
[[ 0 2 3 4 5 0]
[ 2 8 9 10 11 6]
[ 8 14 15 16 17 12]
[ 0 14 15 16 17 0]]