Я недавно узнал о strides в ответе на этот пост и задался вопросом, как я могу использовать их для вычисления фильтра скользящего среднего более эффективно, чем то, что я предложил в этом посте (используя фильтры свертки).
Вот что у меня получилось на данный момент. Он берет представление исходного массива, затем сворачивает его на необходимую величину и суммирует значения ядра для вычисления среднего. Я знаю, что края обрабатываются неправильно, но я могу позаботиться об этом позже... Есть ли лучший и более быстрый способ? Цель состоит в фильтрации больших массивов с плавающей запятой размером до 5000x5000 x 16 слоев, задача, с которой scipy.ndimage.filters.convolve
справляется довольно медленно.
Обратите внимание, что я ищу 8-соседнюю связность, то есть фильтр 3x3 берет среднее значение из 9 пикселей (8 вокруг фокального пикселя) и присваивает это значение пикселю в новом изображении.
import numpy, scipy
filtsize = 3
a = numpy.arange(100).reshape((10,10))
b = numpy.lib.stride_tricks.as_strided(a, shape=(a.size,filtsize), strides=(a.itemsize, a.itemsize))
for i in range(0, filtsize-1):
if i > 0:
b += numpy.roll(b, -(pow(filtsize,2)+1)*i, 0)
filtered = (numpy.sum(b, 1) / pow(filtsize,2)).reshape((a.shape[0],a.shape[1]))
scipy.misc.imsave("average.jpg", filtered)
EDIT Уточнение того, как я вижу, как это работает:
Текущий код:
Я надеялся на лучшее использование stride_tricks для получения 9 значений или суммы элементов ядра напрямую, для всего массива, или на то, что кто-то сможет убедить меня в другом более эффективном методе...