MATLAB: Finding the means of a large number of individual matrices.

for loopimage processingmatrixmatrix arraymean

As part of an image processing task, I've split a 944×752 (grayscale) image into 11092 8×8 matrices. I've tried using the following for loop to calculate and individually store the means of each matrix:
start=0;
stop=11091;
for cell=start:1:stop
m=mean2(['out_' int2str(cell)]);
eval(['xbar_' int2str(cell) '=m'])
end
This is coming up with results, but the numbers are completely incorrect, for example if I manually enter;
k=mean2(out_3953)
Then k=148.3594, but if I call the result for the corresponding 8×8 block as produced by my for loop, the outcome is 81.375.
I'm new to Matlab and coding in general, so any help or advice would be greatly appreciated.

Best Answer

You've really have numbered variables all the way up to out_11091? Wow!
In this forum, we keep telling people not to use eval just to avoid this issue. As soon as you start numbering variables, you're doing it wrong. Very wrong if your numbers go all the way to 11091. Use an array of variable (cell array) or matrices of higher dimension to store all these related variables.
In your case:
%someimage: 2D matrix that can be divided evenly into 8x8 blocks
assert(all(mod(size(someimage), 8) == 0), 'image cannot be divided evenly into 8x8 blocks')
blocks = mat2cell(someimage, repmat(8, 1, size(someimage, 1)/8), repmat(8, 1, size(someimage, 2)/8) %divide image into 8x8 blocks. Store blocks into cell array
xbar = zeros(size(blocks)); %predeclare for faster code
for ib = 1:numel(blocks)
xbar(ib) = mean2(blocks{ib});
end
See how easy the loop is. You don't even need the loop if you use cellfun:
%no need to predeclare xbar since it's created by cellfun
xbar = cellfun(@mean2, blocks);
edit: or as Adam suggest instead of a cell array use a 3D matrix. Easily obtained from the blocks cell array
blocks3D = cat(3, blocks{:});
and the mean is then:
xbar = mean(mean(blocks3D, 1), 2);
The downside of this is you loose the shape of the block matrix. You could always reshape xbar afterward:
xbar = reshape(xbar, size(someimage)/8)