Недавно я узнал о 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)
ИЗМЕНИТЬ Разъяснение того, как я вижу это:
Текущий код:
- используйте stride_tricks для создания массива типа [[0,1,2], [1,2,3], [2,3,4]...], который соответствует верхней строке ядра фильтра.
- Сверните по вертикальной оси, чтобы получить среднюю строку ядра [[10,11,12], [11,12,13], [13,14,15]...] и добавить ее в массив Я попал в 1)
- Повторите, чтобы получить нижнюю строку ядра [[20,21,22], [21,22,23], [22,23,24]...]. В этот момент я беру сумму каждой строки и деля ее на количество элементов в фильтре, давая мне среднее значение для каждого пикселя (сдвинутое на 1 строку и 1 столбец и с некоторыми нечеткими границами по краям, но я могу позаботьтесь об этом позже).
Я надеялся, что лучше использовать stride_tricks, чтобы получить 9 значений или сумму элементов ядра напрямую, для всего массива или что кто-то может убедить меня в еще одном более эффективном методе...