How to change 4x4 matrix to 2x2 matrix
Afficher commentaires plus anciens
I have a 4x4 matrix A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
Now, I'd like to change the matrix size from 4x4 to 2x2 and have the average of 4 cells for new cell.
To visualize,
*1 2* 3 4
*2 3* 4 5
3 4 5 6 2 4
4 5 6 7 --> 4 6
Any input would be appreciated,
Réponses (7)
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
B = cellfun(@mean,cellfun(@mean,mat2cell(A,[2 2],[2 2]),'UniformOutput',false))
A =
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
B =
2 4
4 6
Note : you can simplify by decomposing in several steps if you prefer.
1 commentaire
Jan
le 9 Nov 2014
This is surprisingly slow: it needs about 100 times longer than the other M-versions posted here.
James Tursa
le 7 Nov 2014
Modifié(e) : James Tursa
le 7 Nov 2014
Yet another way (not necessarily any better than other posts), generalized:
kr = 2; kc = 2; % Row and Column sizes of sub-block
[m n] = size(A); mk = m/kr; nk = n/kc; % Size of input and result
B = reshape(sum(reshape(reshape(sum(reshape(A,kr,[])),mk,[]).',kc,[])),nk,mk).'/(kr*kc);
Anew = sepblockfun(A,[2,2],@mean);
Jan
le 7 Nov 2014
1 vote
Image Analyst
le 7 Nov 2014
Did you try the straightforward:
out = [A(1,1)+A(1,2)+A(2,1)+A(2,2),...
A(1,3)+A(1,4)+A(2,3)+A(2,4);...
A(3,1)+A(3,2)+A(4,1)+A(4,2),...
A(3,3)+A(3,4)+A(4,3)+A(4,4)]/4
Azzi Abdelmalek
le 7 Nov 2014
A = [1 2 3 4; 2 3 4 5; 3 4 5 6; 4 5 6 7]
[n,m]=size(A)
[ii1,jj1]=ndgrid(1:2:n,1:2:m)
out=arrayfun(@(x,y) mean(mean(A(x:x+1,y:y+1))),ii1,jj1)
Some timings for a 1024*768 image, 100 iterations (Matlab R2011b, Win7/64, Core2Duo):
BlockMean: 0.35 sec
CELLFUN: 784.0 sec (wow!)
SUM(RESHAPE): 8.37 sec
SUM(RESHAPE) 2: 5.70 sec
ARRAYFUN: 9.74 sec
SEPBLOCK: 7.50 sec
(BLOCKPROC: Undefined function, I do not have the required toolbox)
function SpeedTest(A)
A = rand(1024, 768);
n = 100;
tic;
for k = 1:n
r = BlockMean(A, 2, 2);
end
fprintf('BlockMean: %.4g sec\n', toc);
tic;
for k = 1:1
[m, n] = size(A);
r = cellfun(@mean, ...
cellfun(@mean, ...
mat2cell(A, repmat(2, 1, m/2), repmat(2, 1, n/2)),'UniformOutput',false));
end
fprintf('CELLFUN: %.4g sec\n', toc * 100);
tic;
for k = 1:n
kr = 2;
kc = 2;
[m, n] = size(A);
mk = m/kr;
nk = n/kc;
B = reshape(sum(reshape( ...
reshape(sum(reshape(A,kr,[])), mk,[]).', kc, [])), nk, mk).' / (kr*kc);
end
fprintf('SUM(RESHAPE): %.4g sec\n', toc);
tic;
for k = 1:n
V = 2;
W = 2;
[M, N] = size(A);
AM = reshape(A, V, M/V, W, N/W, []);
r = sum(sum(AM, 1), 3) .* (1.0 / (V * W));
end
fprintf('SUM(RESHAPE) 2: %.4g sec\n', toc);
tic;
for k = 1:1
[n,m] = size(A);
[ii1, jj1] = ndgrid(1:2:n,1:2:m);
r = arrayfun(@(x,y) mean(mean(A(x:x+1,y:y+1))),ii1,jj1);
end
fprintf('ARRAYFUN: %.4g sec\n', toc);
tic;
for k = 1:n
r = sepblockfun(A, [2,2], @mean);
end
fprintf('SEPBLOCK: %.4g sec\n', toc);
tic;
for k = 1:n
r = blockproc(A,[2,2], @(x) mean(x.data(:)) )
end
fprintf('BLOCKPROC: %.4g sec\n', toc);
1 commentaire
Image Analyst
le 9 Nov 2014
Modifié(e) : Image Analyst
le 9 Nov 2014
Why did you run the cellfun and arrayfun tests only 1 iteration instead of n iterations like the other tests? By the way, 1 iteration of blockproc took 12 seconds.
Catégories
En savoir plus sur Programming dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!