Sliding max window and its average for multi-dimensional arrays

后端 未结 3 1292
暖寄归人
暖寄归人 2021-02-08 08:59

I have a 60 x 21 x 700 matrix, where the 60 x 21 represent a pressure output x number of frames. I want to find the 2 x

相关标签:
3条回答
  • 2021-02-08 09:25

    One other approach using 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); 
    

    Results:

    >> 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
    
    0 讨论(0)
  • 2021-02-08 09:30

    2D Arrays: For the given 2D array input, you can use 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)
    

    Sample step-by-step run of the code -

    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
    

    Multi-dimensional Arrays: For multi-dimensional array case, you need to perform 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)
    

    Sample input, output -

    >> 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
    
    0 讨论(0)
  • 2021-02-08 09:32

    A moving average can be done with a simple convolution. It has to be 2D in your case, so:

    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
    

    Produces:

    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
    

    Which is exactly the average of each of your [2x2] areas.

    0 讨论(0)
提交回复
热议问题