Finding Mean for Blocks of Image

Hi all,
I have a 1024x1024 gray image. I want to scan 32x32 pixels window from
top to bottom and left to right in order to find Mean value of each window.
How should i do this?

 Accepted Answer

See this demo. It will be very easy for you to adapt it. Basically you do this:
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:)) * ones(2,2, class(theBlockStructure.data));
blockSize = [32 32];
blockyImage = blockproc(grayImage, blockSize, meanFilterFunction);
Here's the full demo:
% Demo code to divide the image up into 16 pixel by 16 pixel blocks
% and replace each pixel in the block by the median, mean, or standard
% deviation of all the gray levels of the pixels in the block.
%
clc;
clearvars;
close all;
workspace;
fontSize = 16;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
if ~exist(folder, 'dir')
% If that folder does not exist, don't use a folder
% and hope it can find the image on the search path.
folder = [];
end
baseFileName = 'cameraman.tif';
fullFileName = fullfile(folder, baseFileName);
grayImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage)
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Position', get(0,'Screensize'));
set(gcf,'name','Image Analysis Demo','numbertitle','off')
% Define the function that we will apply to each block.
% First in this demo we will take the median gray value in the block
% and create an equal size block where all pixels have the median value.
% Image will be the same size since we are using ones() and so for each block
% there will be a block of 8 by 8 output pixels.
medianFilterFunction = @(theBlockStructure) median(theBlockStructure.data(:)) * ones(size(theBlockStructure.data), class(theBlockStructure.data));
% Block process the image to replace every pixel in the
% 8 pixel by 8 pixel block by the median of the pixels in the block.
blockSize = [8 8];
% Quirk: must cast grayImage to single or double for it to work with median().
% blockyImage8 = blockproc(grayImage, blockSize, medianFilterFunction); % Doesn't work.
blockyImage8 = blockproc(single(grayImage), blockSize, medianFilterFunction); % Works.
[rows columns] = size(blockyImage8);
% Display the block median image.
subplot(2, 2, 2);
imshow(blockyImage8, []);
caption = sprintf('Block Median Image\n32 blocks. Input block size = 8, output block size = 8\n%d rows by %d columns', rows, columns);
title(caption, 'FontSize', fontSize);
% Block process the image to replace every pixel in the
% 4 pixel by 4 pixel block by the mean of the pixels in the block.
% The image is 256 pixels across which will give 256/4 = 64 blocks.
% Note that the size of the output block (2 by 2) does not need to be the size of the input block!
% Image will be the 128 x 128 since we are using ones(2, 2) and so for each of the 64 blocks across
% there will be a block of 2 by 2 output pixels, giving an output size of 64*2 = 128.
% We will still have 64 blocks across but each block will only be 2 output pixels across,
% even though we moved in steps of 4 pixels across the input image.
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:)) * ones(2,2, class(theBlockStructure.data));
blockSize = [4 4];
blockyImage64 = blockproc(grayImage, blockSize, meanFilterFunction);
[rows columns] = size(blockyImage64);
% Display the block mean image.
subplot(2, 2, 3);
imshow(blockyImage64, []);
caption = sprintf('Block Mean Image\n64 blocks. Input block size = 4, output block size = 2\n%d rows by %d columns', rows, columns);
title(caption, 'FontSize', fontSize);
% Block process the image to replace every pixel in the
% 8 pixel by 8 pixel block by the standard deviation
% of the pixels in the block.
% Image will be smaller since we are not using ones() and so for each block
% there will be just one output pixel, not a block of 8 by 8 output pixels.
blockSize = [8 8];
StDevFilterFunction = @(theBlockStructure) std(double(theBlockStructure.data(:)));
blockyImageSD = blockproc(grayImage, blockSize, StDevFilterFunction);
[rows columns] = size(blockyImageSD);
% Display the block standard deviation filtered image.
subplot(2, 2, 4);
imshow(blockyImageSD, []);
title('Standard Deviation Filtered Image', 'FontSize', fontSize);
caption = sprintf('Block Standard Deviation Filtered Image\n32 blocks. Input block size = 8, output block size = 1\n%d rows by %d columns', rows, columns);
title(caption, 'FontSize', fontSize);

5 Comments

why do we multiply by ones in the function ?
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:)) * ones(2,2, class(theBlockStructure.data));
You don't have to. It just replicates the output like the comments say. Let's say you have a blocksize of 2 and 1000 columns in your image. If you omit the ones(2,2) then your output image will be will be 500 columns wide because it has a value for every 2x2 window location. But if you use ones(N, N) then that one value will be replicated N times before it's put into the final output image. So let's say you had a block size of 2, then instead of one value for each window location, you're getting a 2x2 matrix of values for that location. So now the image will be 1000 pixels across - same size as the input image, it just looks blockier. Now let's say you used ones(5,5), so a single value is now a 5x5 matrix meaning the output won't be 500 wide anymore, it will be 500 * 5 = 2500 pixels wide.
Another example, let's say your block size is 100 and your image is 1000 rows and columns. so without ones() we can fit the 100x100 block in there 10 times across and vertically, so the output image is only 10x10 pixels. But let's say that you used ones(64,64). Now each pixel will be replicated 64 times so instead of a 10x10 image it will now be a 640x640 output image.
Try experimenting around with the values and you'll eventually understand.
Thank you for reply image analyst
I experemented with some images and checked the result values, in my case i devided an image of 80x120 pixel into 8x8 blocks and i want to calculate the mean of each block, i used the function to do that and i was curious to know why the "ones". So while exprementing the output was 16x16. i still don"t get the purpose of it since without the ones the result is 8x8 which is expected since we're calculating the mean and supposed to have one value for each block, and this specially if we'll be having more operations on the output image.
I don't see any way you'd get an output of 16 by 16.
If you use a blocksize of 8 with an image of 80x120, and don't use the ones(), the result will be 10 by 15. NOT 8 by 8.
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:));
blockSize = [8, 8];
blockyImage = blockproc(grayImage, blockSize, meanFilterFunction);
How could it be giving you 8 by 8???? With 80 rows you can fit 10 tiles vertically and with 120 columns you can fit 15 tiles (of width 8) horizontally. so the output image should be 10x15, not 8x8.
If you want an output of 8x8 you'd need 8 tiles of height 10, and 8 tiles of width 120/8 = 15. And don't use ones. Then, with
meanFilterFunction = @(theBlockStructure) mean2(theBlockStructure.data(:));
blockSize = [10, 15];
blockyImage = blockproc(grayImage, blockSize, meanFilterFunction);
the output will be 8x8.

Sign in to comment.

More Answers (2)

img = rand(1024, 1024);
b = reshape(img, 32, 32, 32, 32);
m = squeeze(sum(sum(b, 1), 3) / (32*32));
neelavathi d
neelavathi d on 18 Mar 2016
how to find the mean value for each block

Tags

Community Treasure Hunt

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

Start Hunting!