15 views (last 30 days)

Show older comments

Sean de Wolski
on 22 Apr 2011

A couple of calls to convn. The first call will determine the number of zeros; the second will calculate the sum of all values in the sub array; array divide the second by the first.

If you don't want to do it to EVERY POSSIBLE subarray, use blkproc or blockproc with function handle

@(x)sum(x(:))./(sum(logical(x(:)))

Also be aware that since your data type is uint32, if the sum of the 92*92*4 values exceeds 4,294,967,295 it will truncate to 4,294,967,295 and your mean will be wrong.

Sean de Wolski
on 22 Apr 2011

doc blkproc. The function I wrote would be the handle you would feed it.

Something like:

mean_wout_zeros = blkproc(Data,[92 92],@(x)sum(x(:))./(sum(logical(x(:))));

But I just remembered that blkproc is only for 2-dimensions so forget the whole thing.

Sean de Wolski
on 22 Apr 2011

Here's a 2-dimensional example that demonstrates the logic and kernels.

%sample data

A = uint32(repmat(magic(10),[4,1]));

A(A<10) = 0;

%We will use a window size 6x10

window = ones(6,10);

nnzeros = conv2(double(logical(A)),window,'valid'); %you can change this shape do whatever it is you want at the edges.

winsum = conv2(double(A),window,'valid');

mean_wout_zeros = winsum./nnzeros;

%check that it worked (for first valid value)

isequal(sum(sum(A(1:6,:)))/nnz(A(1:6,:)),mean_wout_zeros(1))

You could convert mean_wout_zeros back to uint32 if you want...

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!