#arrays #matlab
#массивы #matlab
Вопрос:
Я пытаюсь сгладить временную историю каждого пикселя в моей матрице — другими словами, пытаюсь сгладить каждый пиксель как по «пространству» (mxn), так и по «времени» (третье измерение). Я использую функцию movmean для создания среднего значения каждого пикселя по времени матрицы 1000x1000x8.
В настоящее время я использую следующий код для получения среднего значения, используя размер окна 5, работающий по третьему измерению:
av_matrix = movmean(my_matrix,5,3)
Это создает среднее значение, как и ожидалось, но мне интересно, работает ли окно только в направлении mxn, а не принимает среднее значение по третьему измерению.
Комментарии:
1. Я думаю,
av_matrix = movmean(my_matrix,5,3);
применяет окно только по 3-му измерению. Таким образом, окно представляет собой вектор длины5
вдоль 3-го dim, а не5x5
матрицу. Что именно вы хотите сделать?2. Вы спрашиваете, работает ли функция так, как задокументировано, или нет? Если вы хотите проверить, что эта функция усредняет только по 3-му измерению, вы можете создать тестовое изображение, для которого вы знаете, каким должен быть результат, затем применить фильтр и проверить. Лучшее тестовое изображение здесь
a=zeros(5,5,10); a(3,3,5)=1;
.
Ответ №1:
Чтобы вычислить скользящее среднее по n измерениям n-мерного массива («окно» представляет собой n-мерный прямоугольник), самый простой способ — использовать свертку (см. convn
).
Вам нужно быть осторожным с краевыми эффектами, то есть когда ядро свертки (или n-мерное окно) частично выскальзывает из данных. movmean
Усредняет только фактические точки данных. Для достижения такого поведения вы можете
- вычислите сумму по ядру с помощью свертки с
'same'
опцией; и затем - разделите каждую запись на количество фактических точек данных, из которых она была вычислена. Это число также можно получить с помощью свертки, а именно, применяя ядро к массиву единиц.
Итак, все, что вам нужно, это:
my_matrix = randi(9,5,5,3); % example 3D array
sz = [3 3 2]; % 3D window size
av_matrix = convn(my_matrix, ones(sz), 'same') ... % step 1
./convn(ones(size(my_matrix)), ones(sz), 'same'); % step 2
Проверьте:
В следующих примерах используется
>> my_matrix
my_matrix(:,:,1) =
6 8 2 1 8
4 6 7 9 8
4 5 1 4 3
5 5 8 7 9
3 6 6 4 9
my_matrix(:,:,2) =
8 8 5 3 6
8 9 6 9 1
9 5 6 2 2
1 7 4 1 2
5 4 7 4 9
my_matrix(:,:,3) =
6 5 8 6 6
1 6 8 6 1
5 5 1 6 7
1 1 2 9 8
1 2 6 1 2
С граничными эффектами:
>> mean(mean(mean(my_matrix(1:2,1:2,1:2))))
ans =
7.125000000000000
>> av_matrix(1,1,1)
ans =
7.125000000000000
Без граничных эффектов:
>> mean(mean(mean(my_matrix(1:3,1:3,1:2))))
ans =
5.944444444444445
>> av_matrix(2,2,1)
ans =
5.944444444444445