user2752148
user2752148

Reputation: 31

Efficient way to apply function to every submatrix of a given size in MATLAB

In MATLAB, I want to apply a function to each submatrix of the given size of a matrix.

My current code works but is very slow.

%inputs
%    f: function to apply to submatrices
%    M: main matrix
%    h: height of submatrices
%    w: width of submatrices
%output
%    out: matrix of results of applying f to submatrices of M
function out = metricmap(f,M,h,w)
    [r,c] = size(M);
    h = h-1;w = w-1; %to make these values deltas 
    out = zeros([r,c]-[h,w]);
    
    for i = 1:(r - h)
        for j = 1:(c - w)
            subM = M(i:(i+h),j:(j+w));
            out(i,j) = f(subM);
        end
    end
end

Any suggestions are greatly appreciated!

Upvotes: 3

Views: 196

Answers (2)

rahnema1
rahnema1

Reputation: 15837

As corr2 is the function that to be applied to submatrices you can use the following vectorized method of computing sliding_corr2(A,B) where size of B is smaller than A:

B_B = B - mean(B(:));
mA = conv2(A, ones(h, w) / (h * w), 'valid');
numerator = conv2(A, flipud(fliplr(B_B)), 'valid') - mA * sum(B_B(:));
denominator = sqrt(                        ...
    (                                      ...
      conv2(A .^ 2, ones(h, w), 'valid') - ...
      (h * w) * (mA .^ 2)                  ...
    )                                      ...
    * (B_B(:).' * B_B(:))                  ...
);
out = numerator ./ denominator;

Assuming that a is i,j sub-matrix of A the corr2 function is formulated as:

enter image description here

It can be rewritten as:

enter image description here

enter image description here

Now it can be written as convolution operations:

enter image description here

Where * is the convolution operator.

Upvotes: 0

tdy
tdy

Reputation: 41327

If you have the image processing toolbox, you can use blockproc to apply f on a [h w] sliding window of M:

out = blockproc(M, [h w], f);

Upvotes: 2

Related Questions