2015-05-06 59 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