2015-05-06 57 views
11

我有一個60 x 21 x 700矩陣,其中60 x 21代表pressure output x number of frames。我想找到2 x 2窗口,它可以生成每幀最大平均壓力並將其存儲在一個新變量中,以便繪製出來。例如,如果矩陣看起來是這樣的:滑動最大窗口及其多維陣列的平均值

01 02 02 01 01 
02 01 01 02 02 
02 03 04 04 03 
01 02 06 10 05 
02 02 08 09 05 

的最大窗口,其平均爲2 x 2窗口會 -

06 10 
08 09 

= 8.25 

所以在我的搜索遠的解決方案,我只是完成已經能夠找到一種方法來獲得最大值(例如,上述矩陣中的10),但實際上無法確定如何從沒有固定索引參考的小區域獲取最大平均值。我對MATLAB相當陌生,所以如果我錯過了一些東西或者根本不瞭解正確的東西,我很抱歉。 任何幫助或指導將不勝感激。

+0

矩陣的維數不能被2整除。你想爲此做什麼? –

+1

@SanthanSalai,我認爲OP正在考慮'滑動'平均值,所以矩陣大小不一定是窗口大小的精確倍數。古馬金,你能否確認或體弱嗎? – Hoki

+0

@Hoki是的,我認爲這將是我最想達到的目標。對不起,如果我的問題不是很清楚。 – Gumajin

回答

13

2D陣列:對於給定的2D陣列的輸入,可以使用2D convolution -

%// Perform 2D convolution with a kernel of `2 x 2` size with all ones 
conv2_out = conv2(A,ones(2,2),'same') 

%// Find starting row-col indices of the window that has the maximum conv value 
[~,idx] = max(conv2_out(:)) 
[R,C] = ind2sub(size(A),idx) 

%// Get the window with max convolution value 
max_window = A(R:R+1,C:C+1) 

%// Get the average of the max window 
out = mean2(max_window) 

樣品一步一步的代碼的運行 -

A = 
    1  2  2  1  1 
    2  1  1  2  2 
    2  3  4  4  3 
    1  2  6 10  5 
    2  2  8  9  5 
conv2_out = 
    6  6  6  6  3 
    8  9 11 11  5 
    8 15 24 22  8 
    7 18 33 29 10 
    4 10 17 14  5 
idx = 
    14 
R = 
    4 
C = 
    3 
max_window = 
    6 10 
    8  9 
out = 
     8.25 

多維陣列:對於多維陣列的情況下,您需要執行ND convolution -

%// Perform ND convolution with a kernel of 2 x 2 size with all ONES 
conv_out = convn(A,ones(2,2),'same') 

%// Get the average for all max windows in all frames/slices 
[~,idx] = max(reshape(conv_out,[],size(conv_out,3)),[],1) 
max_avg_vals = conv_out([0:size(A,3)-1]*numel(A(:,:,1)) + idx)/4 

%// If needed, get the max windows across all dim3 slices/frames 
nrows = size(A,1) 
start_idx = [0:size(A,3)-1]*numel(A(:,:,1)) + idx 
all_idx = bsxfun(@plus,permute(start_idx(:),[3 2 1]),[0 nrows;1 nrows+1]) 
max_window = A(all_idx) 

樣品輸入,輸出 -

>> A 
A(:,:,1) = 
    4  1  9  9 
    3  7  5  5 
    9  6  1  6 
    7  1  1  5 
    4  2  2  1 
A(:,:,2) = 
    9  4  2  2 
    3  6  4  5 
    3  9  1  1 
    6  6  8  8 
    5  3  6  4 
A(:,:,3) = 
    5  5  7  7 
    6  1  9  9 
    7  7  5  4 
    4  1  3  7 
    1  9  3  1 
>> max_window 
max_window(:,:,1) = 
    9  9 
    5  5 
max_window(:,:,2) = 
    8  8 
    6  4 
max_window(:,:,3) = 
    7  7 
    9  9 
>> max_avg_vals 
max_avg_vals = 
      7   6.5   8 
+1

我打算完全一樣。我認爲它是最有效的方式,因爲過去「conv2」的速度非常快。 – thewaywewalk

+0

該死的你總是打敗我這些!好工作;-) – Hoki

+0

@Hoki對不起! :)事實證明,我們甚至不需要在每個窗口中找到平均值。 – Divakar

2

一個使用im2col

%// getting each 2x2 sliding submatrices as columns 
cols = im2col(A,[2 2],'sliding'); 

%// getting the mean & reshaping it to 2D matrix 
C = reshape(mean(cols),size(A,1)-1,[]); 

%// to find the maximum of the sub-matrix-means and its corresponding index. 
[B,i] = max(mean(cols)); 

%// reshaping the corresponding sub-matrix to 2D matrix 
mat = reshape(cols(:,i),2,2); 

結果另一種方法:

>> mat 

mat = 

6 10 
8  9 

>> C 

C = 

1.5000 1.5000 1.5000 1.5000 
2.0000 2.2500 2.7500 2.7500 
2.0000 3.7500 6.0000 5.5000 
1.7500 4.5000 8.2500 7.2500 

>> B 

B = 

8.2500 
+1

感謝您提供另一種方法。 – Gumajin

3

移動平均可以用簡單的卷積來進行。它是2D你的情況,所以:

A = [01 02 02 01 01 
    02 01 01 02 02 
    02 03 04 04 03 
    01 02 06 10 05 
    02 02 08 09 05]; 

B = [1 1;1 1]/4 ; %// prepare moving average filter [2x2] 

C = conv2(A,B,'valid') ; %// perform 2D moving average 

產地:

C = 
    1.5  1.5  1.5  1.5 
    2  2.25 2.75 2.75 
    2  3.75 6  5.5 
    1.75 4.5  8.25 7.25 

這正是你的每一個[2×2]地區的平均水平。

+0

非常感謝。我沒有想到解決方案如此簡單。 – Gumajin