I have a 720 x 1280 matlab array. I need to sum every 5x5, 10x10, 20x20 and then 40x40 sub array within that and then take the average. This then needs to make 4 new arrays with size (720/5, 1280/5), (720/10, 1280/10),(720/20, 1280/20),(720/40, 1280/40), How do I do this with for loops?
CodePudding user response:
As @bla mentioned, traditionally this would not be done using for
loops in MATLAB. Regardless, here is an example:
setup
data = rand(720, 1280);
windowSize = 5
out = nan(size(data)/windowSize);
Here we iterate over each block, where the limits of the block are defined by ((ii-1)*windowSize 1)
and (ii*windowSize)
(e.g. 1:5
, 6:10
, 11:15
).
for ii = 1:size(data, 1)/windowSize
for jj = 1:size(data, 2)/windowSize
currentData = data( ((ii-1)*windowSize 1):(ii*windowSize) ,...
((jj-1)*windowSize 1):(jj*windowSize) );
out(ii,jj) = mean(currentData(:));
end
end
Changing the window size can also be automated using a for
loop, but I will leave this as a homework problem.
CodePudding user response:
For this kind of problems, I feel like converting the matrix into a cell array of blocks and then using cellfun on the blocks makes for a nice and readable code :
data = rand(720, 1280);
[sz1,sz2] = size(data);
wSize = 5;
idx1 = wSize*ones(1,sz1/wSize);
idx2 = wSize*ones(1,sz2/wSize);
% Convert input matrix to a cell array of wSize x wSize blocks
C = mat2cell(data,idx1,idx2);
% Apply the "Take the mean of all elements" function to each blocks
out = cellfun(@(X) mean(X(:)),C);
Note that cellfun
, by default, directly concatenates the outputs into an array.