Создает ли функция movmean в Matlab среднее значение по всем измерениям матрицы?

#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 Усредняет только фактические точки данных. Для достижения такого поведения вы можете

  1. вычислите сумму по ядру с помощью свертки с 'same' опцией; и затем
  2. разделите каждую запись на количество фактических точек данных, из которых она была вычислена. Это число также можно получить с помощью свертки, а именно, применяя ядро к массиву единиц.

Итак, все, что вам нужно, это:

 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