Image / Matrix binning with sum of each bin

88 views (last 30 days)
Hi,
I'm trying to downsample an image/matrix by binning.
What I want to achieve is that each output pixel would be the sum of it's parts.
From what I understood, using the imresize would only be possible with some kind of weighted average and not summing.
Is there a bulit in function that would allow for binning with summing?
If not, what would be the best approach to do that?
Thanks!
O.

Accepted Answer

DGM
DGM on 5 Jan 2022
Avoiding any sort of weighting suggests to me that this is strictly integer-factor downsampling. If that's the case, then one way might be something like this.
blocksize = [2 2]; % downsampling ratio [h w]
A = ones(10) % test array (geometry must be integer-divisible by blocksize)
A = 10×10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
B = mat2cell(A,repmat(blocksize(1),[1 size(A,1)/blocksize(1)]),...
repmat(blocksize(2),[1 size(A,2)/blocksize(2)]));
B = cellfun(@(x) sum(x,'all'),B)
B = 5×5
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
  6 Comments
DGM
DGM on 6 Jan 2022
Edited: DGM on 6 Jan 2022
It always takes me forever to make reshape do what I want, but this might work.
A = kron([1 3 5; 2 4 8; 3 6 9],ones(2)) % makes it easy to follow the numbers
A = 6×6
1 1 3 3 5 5 1 1 3 3 5 5 2 2 4 4 8 8 2 2 4 4 8 8 3 3 6 6 9 9 3 3 6 6 9 9
s = size(A);
bs = [2 2]; % blocksize
B = reshape(A.',bs(1),s(1)/bs(1),[]);
B = reshape(permute(B,[1 3 2]),bs(1),bs(2),[]);
B = sum(sum(B,1),2);
B = reshape(B,s./bs)
B = 3×3
4 12 20 8 16 32 12 24 36
That should be quite a bit faster than using cell operations, even if it's pretty opaque to read.
omri r
omri r on 6 Jan 2022
Edited: omri r on 6 Jan 2022
Thank you very much!
I found another way.
Seems even a bit faster for larege matrices (~2000x2000):
(BTW, that is matters in terms of performance single/multi line codes?)
A = 1:2100^2;
A = reshape(A,2100,[]);
binSize = 3;
% multi line code
tic
C = reshape(A,binSize,[]);
C = sum(C);
C = reshape(C,size(A,1) / binSize,[]);
C = C';
C = reshape(C,binSize,[]);
C = sum(C);
C = reshape(C,size(A,2) / binSize,[]);
C = C';
% combined line code
C = sum(reshape(A,binSize,[]));
C = reshape(C,size(A,1) / binSize,[])';
C = sum(reshape(C,binSize,[]));
C = reshape(C,size(A,2) / binSize,[])';

Sign in to comment.

More Answers (0)

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!