How to implement a function to apply the 3x3 average filter to a gray-scale image.

Here is my code
function AverageFilter(image)
I = imread(image);
[x,y] = size(I);
for i = 2:x-1
for j = 2:y-1
sum = 0;
for ii = i-1:i+1
for jj = j-1:j+1
sum = sum + I(ii,jj);
end
end
I2(i,j) = ceil(sum/9);
end
end
imshow(I2);
it keeps giving me the following error: Warning: Image is too big to fit on screen; displaying at 67% > In imuitools\private\initSize at 73 In imshow at 264 In AverageFilter at 18
and the resulting image is very dark..
I want to know what did i do wrong in my code and to fix this error?!!!

7 Comments

function AverageFilter(image)
I = imread(image);
[x,y] = size(I);
for i = 2:x-1
for j = 2:y-1
sum = 0;
sum=int32(sum);
for ii = i-1:i+1
for jj = j-1:j+1
tmp=I(ii,jj);
tmp=int32(tmp);
sum = sum + tmp;
sum=int32(sum);
end
end
I2(i,j) = ceil(sum/9);
end
end
imshow(uint8(I2)
Logically, what you have posted is correct but technically not. In MATLAB each variable is defined as 8 bit of size by default, So, sum is rounded to 255 while adding pixel values. That is the reason you got dark image at the output i.e., 255/9 =28 after roundoff. Now, to get exact "average" value sum is defined as 32 bit size. tmp is also defined as temporary variable. Then you will get the exact ouput by converting I2 into 8 bit.
sir it is giving the output gray image can u please send me code for the color image
@abhishek KP, try this:
rgbImage = imread('peppers.png');
nexttile
imshow(rgbImage);
drawnow;
windowWidth = 21;
kernel = ones(windowWidth) / windowWidth^2;
blurryImage = imfilter(rgbImage, kernel);
nexttile
imshow(blurryImage);
sir actually what i need is this can u help me with the code sir
sir can u please send me code for this
  1. i am considering 3x3 size window
  2. i am taking the average of the pixels conditons are
- if the pixel values in the window is greater than 255 then i am averaging the pixels expect 255 value pixels
- if the pixel values are less than 255 value pixels then i am taking 255 as my answer
example lets take in a 3x3 window i have 5 number of 255 pixel value and 4 number less than 255 values then 255 > 254 or any other pixel value so i am keeping 255 as same if 255< 254 or any other pixel values then i am averaging all the pixels except 255 pixel value
3. after this i have to replace the pixel value by resultent value
anyone can write code for this please as soon as possible
sir I need to ignore high intensity pixel 255 and have to average all other pixels in the 3x3 window If all the pixels are white that is high intensity pixels 255 then I have keep it as 255 - sir here is the condition 1. While sliding a 3x3 window on image 2.if there are white(255) pixels are more than other pixels then I have to keep 255 and replace center pixel value by 255 3.if there are below (255) pixels are more inside that 3x3 window... Then I have to take average of below(255)pixels then have to take average of only below(255) pixels and replace as the center pixel value I have to take 255(white pixels) as center during sliding a 3x3 window I need a code for it please do help with loop I need because I have to take all 255(white)pixels in a image and have to change the value of each and every white pixel
Sir I have found out the pixel values using coordinates (x, y) = find(I==255) I got the each and every coorodintes and pixels of 255(white) from this now I need to apply averaging as I explained above for every pixel Please do help me with the code
@abhishek KP, since you are not asking @amy elmossly to clarify anything on her 9 year old post, you should start your own question. In that new question I will show you how to do it with two convolutions (one to sum and one to count) and an assignment of the 255s.
ok sir now i will tag u and will write a question
thank you i need it as soon as possible

Sign in to comment.

 Accepted Answer

Don't worry about the warning. Your code can be done like this:
blurredImage = conv2(single(yourGrayScaleImage), ones(3)/9, 'same');
imshow(blurredImage, []); % or imshow(uint8(blurredImage), [0 255]);

12 Comments

hello!
i would like to know how to implement a function to apply the 9x9 average filter to a gray-scale image.
thank you
Try this:
windowSize = 9; % Whatever odd number you want. Larger = more blur.
kernel = ones(windowSize) / windowSize ^ 2;
blurredImage = conv2(single(yourGrayScaleImage), kernel, 'same');
imshow(blurredImage, []); % or imshow(uint8(blurredImage), [0 255]);
Hello! I want to implement the 3x3 and 9x9 median filter to a gray-scale image, could you help me please?
Thank you!
Franzi, simply call medfilt2(grayImage, [3,3])
mfImage = medfilt2(grayImage, [3,3]);
hello Image Analyst!
I want to implement without the inbuilt function medfilt2, do you have an idea to implement it with conv2, like you did it above for the average filter?
Convolution is a linear filter. Median is a nonlinear filter. You can't implement a median filter with conv2(). You could use median() and nlfilter() and I'm attaching a general purpose demo for nlfilter. However median() and nlfilter() also built in functions. So if you're not going to use built-in functions like sort(), median(), etc. you're going to have to sort the values in the window yourself, then take the middle one. I'm attaching a scanning program that is basically a manual convolution but in the deepest level of the for loop you're going to have to do your own home-built median filter function instead of just computing the sum and average like I did to do the blur. I'm sure you can find sorting algorithm pseudocode on the web, or maybe even manual MATLAB sorting code.
Ok, so if I want to implement it with the built in function median(), the code would be newImage = median(grayImage, [3,3]) ?
No that would be if you want to use medfilt2().
median() gives the median value of the whole image, not the median value in a scanning window to create an output image.
If you're going to use median() and not medfilt2() then you need to use nlfilter() (if you're allowed to) and then use median() in the custom function that nlfilter() calls.
I don't think I'm allowed to use the nlfilter() because we haven't learnd this filter yet. We are only allowed to use median() and reshape() but I have no idea how. Do you have an idea how to implement it with these two functions?
Hello? Are you still there? Do you know the function reshape and how to use it?
You'd have to reshape the image into a column of 3 pixels. Then use repelem() to repeat each column because the windows overlap don't they? You don't want them to jump, right. Then use a for loop to go down the columns. You'd have to think about it. It gets tricky because you'll have to have each pixel in there 9 times so it's tricky to figure out how to do that with repelem() and reshape(). It's much more difficult when they don't let you do it the simple and obvious ways. It's MUCH easier if they let you move the window in jumps of 3 pixels over and down rather than 1 pixel over and down.

Sign in to comment.

More Answers (2)

Dont worry about Warning/Display Warning of too big size, you can simply write warning off at the starting of program.
img = imread("Tulip.jpg");
[row ,col] = size(img);
for i = 2:1:row-1
for j = 2:1:col-1
x= img(i+1:i-1,j+1:j-1);
C=x(:)';
C=sort(C);
avg = sum(C)/9;
img(i,j) = avg;
end
end
imshow(img);

4 Comments

i have a problem to run this code.Output is showing black screen
clc
clear
close all
img = imread('E:\matlab project\image processing\Fig0121(b)(blown_ic_hr).tif');
[row ,col] = size(img);
for i = 2:1:row-1
for j = 2:1:col-1
x= img(i-1:i+1,j-1:j+1);
C=x(:);
%C=sort(C);
avg = sum(C)/9;
I2(i,j) =ceil(avg);
I2=uint8(I2);
end
end
figure(1);
subplot(1,2,1);
imshow(img);
subplot(1,2,2);
imshow(I2);
imtool(I2);
imtool(img);
I write for you the correct code
If you're going to offer an improved bit of code, explain why it's better.
This is still a lot of room for improvement.
% read an image
inpict = imread('cameraman.tif'); % use unambiguous variable names
% what stops this from breaking if the image is RGB?
[row,col,~] = size(inpict); % always discard the last output from size()
outpict = zeros(row,col,class(inpict)); % preallocate to appropriate class
for i = 2:1:row-1 % avoiding the edges is a simple strategy, but not very good
for j = 2:1:col-1 % a better way would be edge padding/replication
% get a sample
sampleblock = inpict(i-1:i+1,j-1:j+1);
% don't need a bunch of temporary variables or unused lines
% RHS is uint8-scale double
% LHS is uint8
% the assignment implicitly uses round() when casting
outpict(i,j) = mean(sampleblock(:));
end
end
% don't need a bunch of redundant images
montage({inpict outpict})
Communication is the purpose of a forum, and comments (code comments and external commentary) are part of that process.

Sign in to comment.

Asked:

on 14 Nov 2012

Edited:

DGM
on 27 Nov 2022

Community Treasure Hunt

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

Start Hunting!