making coarse matrix from fine resolution matrix

18 views (last 30 days)
Hi, I am trying to make a coarse resolution matrix of 3600x1800 from a 8640x4320 matrix by summing up the elements of the matrix.
Hi am trying the following: However this doesnot work with fractions (here, 2.4)
%%%%Z1 is the original 8640x4320 matrix
abc = blockproc(Z1,[2.4,2.4],@(x)sum(x.data));
abc1 = blockproc(abc,[1,2.4],@(x)sum(x.data));

Accepted Answer

Matt J
Matt J on 23 Jan 2020
Edited: Matt J on 27 Jan 2020
A 3rd approach, more memory conserving and faster,.
Z1=randi(100,8640,4320);
u = 5; %upsampling factor
d = 12; %downsampling factor
t = d/u; %reduction factor
[m,n]=size(Z1);
L1=speye(m); L2=speye(round(m/t))/u;
R1=speye(n); R2=speye(round(n/t))/u;
L=repelem(L2,1,d) * repelem(L1,u,1);
R=(repelem(R2,1,d) * repelem(R1,u,1)).';
tic
abc4= L*(Z1*R);
toc
Note as well that the matrices L and R are reusable on other Z1 of the same size that one might wish to downsample later on.

More Answers (2)

Matt J
Matt J on 23 Jan 2020
Edited: Matt J on 23 Jan 2020
If you have the Image Processing Toolbox,
abc1=imresize(Z1,[3600,1800])
  10 Comments
Matt J
Matt J on 23 Jan 2020
Edited: Matt J on 23 Jan 2020
This should give proper agreement in the sums
abc3=imresize(Z1,1/2.4)*2.4^2;
or
abc3=imresize(Z1,1/2.4);
abc3=abc3/sum(abc3(:))*sum(Z1(:));

Sign in to comment.


SChow
SChow on 23 Jan 2020
Edited: SChow on 23 Jan 2020
scaling = 5; %%% I scale Z1 by factor of 5 so that sepblockfun works,
%%%%% sepblockfun is developed by MattJ and is available for
%downlaod at https://de.mathworks.com/matlabcentral/fileexchange/48089-separable-block-wise-operations
S = repelem (Z1 / scaling ^ 2, scaling, scaling); %% where S is 43200x21600
abc2 = sepblockfun (S, [12,12], 'sum' ); %%% abc2 is 3600x1800
  4 Comments
SChow
SChow on 10 Sep 2020
Edited: SChow on 10 Sep 2020
Hi @Matt J,
Is there a way to use sepblockfun if the matrix contains NaN values?
in other words, it does not seem to support functions - 'nansum' / 'nanmean'
Matt J
Matt J on 10 Sep 2020
Edited: Matt J on 10 Sep 2020
You can do,
S = sepblockfun( repelem (Z1 , scaling, 1) , [12,1], @nansum);
abc2 = sepblockfun( repelem (S, 1, scaling) , [1,12], @nansum)/scaling^2;
You cannot apply sepblockfun to nanmean directly, because nanmean is not separable, e.g.
>> A=rand(5); A(1:3)=nan
A =
NaN 0.9730 0.8253 0.8314 0.4168
NaN 0.6490 0.0835 0.8034 0.6569
NaN 0.8003 0.1332 0.0605 0.6280
0.6596 0.4538 0.1734 0.3993 0.2920
0.5186 0.4324 0.3909 0.5269 0.4317
>> nanmean(nanmean(A,1),2)
ans =
0.5163
>> nanmean(nanmean(A,2),1)
ans =
0.5142
However, you can implement block-wise nanmean indirectly by using the separability of nansum,
>> sepblockfun(A,[5,5],@nansum)./sepblockfun(~isnan(A),[5,5],@nansum)
ans =
0.5063
>> nanmean(A(:))
ans =
0.5063

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!