# how to avoid for loops or faster way for compute 3x3 avarage value of an image

7 views (last 30 days)
ali eskandari on 19 Oct 2020
Edited: Image Analyst on 19 Oct 2020
I have a few pixels in an image and I want to calculate the average values ​​of a 3x3 window centred on those pixels in Matlab. It should be noted that not all over the image, just a few desired pixels.
I tried this code and it works but I prefer to avoid using for loops. Is there another way for doing that?
clc
clear
close all
x= [10,15,20];
y= [15,25,35];
m=-1;
n=-1;
window = zeros(3,3);
Avg = zeros(max(size(x)),1)
for k=1:max(size(x))
for i = 1:3
for j=1:3
window(i,j) = img(x(k)+m,y(k)+n);
n=n+1;
end
n=-1;
m=m+1;
end
Avg(k) = mean(window,'all')
end

Image Analyst on 19 Oct 2020
Edited: Image Analyst on 19 Oct 2020
If you're only doing it at 3 locations, don't worry about using for loops. It will be fast.
If you insist on using built-in functions to process the whole image, then...
Use imfilter():
kernel = ones(3)/9;
outputImage = imfilter(grayImage, kernel);
Or you can use conv2():
kernel = ones(3)/9;
outputImage = conv2(double(grayImage), kernel, 'same');
then you can reference outputImage(row, col) for the desired locations. Just be aware that y comes first, not x, so it's outputImage(y(1), x(1)), NOT outputImage(x(1), y(1)).

Show 1 older comment
ali eskandari on 19 Oct 2020
For instance, I have some x&y positions and I want to compute a 3x3 avarage window around each pixel. Your code will do another thing.
ali eskandari on 19 Oct 2020
Thank you for your answer, the problem is that I have around 100 images and I want to apply this method on all of them and honestly there are more than three locations. Besides, I should add this code to other computations so the speed of computation is so important for me, that is why I am looking for a faster way. I just applyed it on one image to see how does it work.
Image Analyst on 19 Oct 2020
Try this:
x = [10, 15, 20];
y = [15, 25, 35];
windowWidth = 3;
halfWidth = floor(windowWidth/2)
Avg = zeros(length(x), 1);
for k = 1 : length(x)
% Convert x and y into row and column.
row = y(k);
col = x(k);
% Get subimage centered about the (x, y) location.
window = grayImage(row - halfWidth : row + halfWidth, col - halfWidth : col + halfWidth);
% Compute the mean of that subimage.
Avg(k) = mean(window,'all')
end
If you have more than a few thousand points in the images to inspect, then it's best to just filter the whole image with conv2() or imfilter() like I originally said, and pluck out the locations you want.
To process a sequence of images, see the FAQ.