mean value of subarrays

3 views (last 30 days)
Hassan
Hassan on 22 Apr 2011
I have a 3-dimensinal array ( 1483 rows, 417 columns and 4 bands). I am trying to get a mean value for each sub-array of 92rows*92columns. I have some zero values that I want to exclude when the calcualtion of mean is being done. I used the following code but it's not correct.my data type is uint32. i apperciate your help.

Accepted Answer

Sean de Wolski
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.
  7 Comments
Hassan
Hassan on 22 Apr 2011
About using Loops, unfortunately I don't know how to use other functions to avoid using Loops.
I don't know the meaning of comman you wrote (@(x)sum(x(:))./(sum(logical(x(:)))).
I replaced 'x' by 'Data' (which is the name of my data) but it didnt give me anything.
Sorry it should be number of non-zeros (n_zeros=sum(new_array(j:j+91,k:k+91,i)~=0)).
still, it's not working. I'm getting the folling error:
??? Index exceeds matrix dimensions.
Error in ==> upscaling at 90
n_zeros=sum(new_array(j:j+91,k:k+91,i)~=0)
Sean de Wolski
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.

Sign in to comment.

More Answers (1)

Sean de Wolski
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...
  4 Comments
Hassan
Hassan on 22 Apr 2011
I am working with a remote sensing image(1483*417*4) which each pixel is 5 meters * 5 meters. i want to average it up for each 92*92 pixels. the new array which has the mean values has 1483/92=16.1 and 417/92=4.5 dimensions. I removed the last 11 rows and added 43 columns (zero values) to create a 16*5 array.
Hassan
Hassan on 22 Apr 2011
As I said I need an array of ean values (16 rows,5coulmns,4 abnds) mean values while using the qhat you said above, I got vecotr of 5540 elements.
it seems blkproc,as you wrote the code above, does what I need.
thanks for the help Sean.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!