Search code examples
matlabmatrix3daveragescilab

How can I build a Scilab / MATLAB program that averages a 3D matrix?


I need to make a scilab / MATLAB program that averages the values of a 3D matrix in cubes of a given size(N x N x N).I am eternally grateful to anyone who can help me.

Thanks in advance


Solution

  • In MATLAB, mat2cell and cellfun make a great team for working on N-dimensional non-overlapping blocks, as I think is the case in the question. An example scenario:

    • [IN]: A = [30x30x30] array
    • [IN]: bd = [5 5 5], size of cube
    • [OUT]: B = [6x6x6] array of block means

    To accomplish the above, the solution is:

    dims = [30 30 30]; bd = [5 5 5];
    A = rand(dims);
    f = floor(dims./bd);
    remDims = mod(dims,bd); % handle dims that are not a multiple of block size
    Ac = mat2cell(A,...
        [bd(1)*ones(f(1),1); remDims(1)*ones(remDims(1)>0)], ....
        [bd(2)*ones(f(2),1); remDims(2)*ones(remDims(2)>0)], .... 
        [bd(3)*ones(f(3),1); remDims(3)*ones(remDims(3)>0)] );
    B = cellfun(@(x) mean(x(:)),Ac);
    

    If you need a full size output with the mean values replicated, there is a straightforward solution involving the 'UniformOutput' option of cellfun followed by cell2mat.

    If you want overlapping cubes and the same size output as input, you can simply do convn(A,ones(blockDims)/prod(blockDims),'same').

    EDIT: Simplifications, clarity, generality and fixes.