Matlab middle filter
I wrote a 3x3 medium filter. It works fine, but it displays the same output image three times instead of one. How to solve a problem?
Code
function [filtr_image] = avgFilter(noisy_image)
[x,y] = size(noisy_image);
filtr_image = zeros(x,y);
for i = 2:x-1
for j =2:y-1
sum = 0;
for k = i-1:i+1
for l = j-1:j+1
sum = sum+noisy_image(k,l);
end
end
filtr_image(i,j) = sum/9.0;
filtr_image = uint8(filtr_image);
end
end
end
early
source to share
I can't figure out why your code will repeat the image (unless the pattern is caused by an integer overflow: /), but here are some tips:
if you want to use for loops, at least remove the inner loops:
[x,y] = size(noisy_image);
filtr_image = zeros(x,y);
for i = 2:x-1
for j =2:y-1
% // you could do this in 1 line if you use mean2(...) instead
sub = noisy_image(i-1:i+1, j-1:j+1);
filtr_image = uint8(mean(sub(:)));
end
end
But do you know about convolution? Matlab has a built-in function for this:
filter = ones(3)/9;
filtr_image = uint8(conv2(noisy_image, filter, 'same'));
source to share
Which is most likely due to the fact that you are supplying the image with a color when the code is specifically for grayscale. Let this be a lesson for you to blindly copy code from source without fully understanding it.
The reason you see "three" is because when you do this to highlight your output filter:
[x,y] = size(noisy_image)
If you have a 3D matrix the number of columns reported size
will be y = size(noisy_image,2)*size(noisy_image,3);
. This way, when you iterate over each pixel in your image, in the top column order, each plane will be positioned side by side. What you need to do is either convert the image to grayscale from RGB or filter each plane separately.
In addition, unnecessary casting is performed in the loop. Just do it outside of the loop.
Option number 1 - Filter on a plane
function [filtr_image] = avgFilter(noisy_image)
[x,y,z] = size(noisy_image);
filtr_image = zeros(x,y,z,'uint8');
for a = 1 : z
for i = 2:x-1
for j =2:y-1
sum = 0;
for k = i-1:i+1
for l = j-1:j+1
sum = sum+noisy_image(k,l,a);
end
end
filtr_image(i,j,a) = sum/9.0;
end
end
end
end
Then you would call it by:
filtr_image = avgFilter(noisy_image);
Option # 2 - Convert to grayscale
filtr_image = avgFilter(rgb2gray(noisy_image));
Minor note
You are using sum
as a variable. This is a very bad choice. sum
is an actual function in MATLAB and you will obscure that function with your variable. This will lead to unintended consequences if you have other functions that rely on sum
for subsequent line-by-line work.
source to share