nos
nos

Reputation: 20870

Sum over blocks in a 3D matrix - MATLAB

For a 3N by 3N by 3N matrix A, I would like to derive a N by N by N matrix B whose entries come from summation over blocks in A.

For example, B(1,1,1) = sum of all elements of A(1:3,1:3,1:3).

Basically, A is kind of a high resolution matrix and B is a low resolution matrix from summing over entries in A.

Upvotes: 3

Views: 871

Answers (3)

Luis Mendo
Luis Mendo

Reputation: 112749

If memory is not a concern, you can use a "labelling" approach: build a 3-component label to group the elements of A, and use that label as the first input argument to accumarray to do the sum. The label uses integers from 1 to N, so the result of accumarray already has the desired shape (NxNxN).

N = 5;
F = 3; %// block size per dimension
A = rand(15,15,15); %// example data. Size FN x FN x FN
[ii jj kk] = ind2sub(size(A), 1:numel(A));
label = ceil([ii.' jj.' kk.']/F);
result = accumarray(label, A(:));

Upvotes: 3

Divakar
Divakar

Reputation: 221614

reshape + sum based approach and as such has to be pretty efficient -

sumrows = sum(reshape(A,3,[]),1);                      %// Sum along rows
sumcols = sum(reshape(sumrows,N,3,[]),2);              %// Sum along cols
B = reshape(sum(reshape(sumcols,N*N,3,[]),2),N,N,N);   %// Sum along 3rd dim

If you are crazy about one-liners, here's that combining all steps into one -

B = reshape(sum(reshape(sum(reshape(sum(reshape(A,3,[]),1),N,3,[]),2),N*N,3,[]),2),N,N,N);

Upvotes: 2

Simon
Simon

Reputation: 32923

For a 2D matrix, this would work:

B = reshape(sum(im2col(A, [3 3], 'distinct')), [N N]);

NB: You need the image processing toolbox.

But for 3D matrices, I don't know of any built-in function equivalent to im2col. You might have to use a loop. Left as an exercise to the reader ;)

Upvotes: 0

Related Questions