# I have created an algorithm for a median RGB image filter, however, it doesn't seem to be working.

2 views (last 30 days)
Lewis Laurence on 22 Jan 2022
Edited: DGM on 23 Jan 2022
clc
I = double(I);
[row, col, dim]=size(w);
red= I(:,:,1);
green= I(:,:,2);
blue= I(:,:,3);
for i = 2:1:row-1
for j = 2:1:col-1
red_f(i,j)=w(1,1)*red(i-1,j-1)+w(1,2)*red(i-1,j)+w(1,3)*red(i-1,j+1)+w(2,1)*red(i,j-1)+w(2,2)*red(i,j)+w(2,3)*red(i,j+1)+...
w(3,1)*red(i+1,j-1)+w(3,2)*red(i+1,j)+w(3,3)*red(i+1,j+1);
red_f=sort(red_f);
I(i,j)= red_f(5);
green_f(i,j)= w(1,1)*green(i-1,j-1)+w(1,2)*green(i-1,j)+w(1,3)*green(i-1,j+1)+w(2,1)*green(i,j-1)+w(2,2)*green(i,j)+w(2,3)*green(i,j+1)+...
w(3,1)*green(i+1,j-1)+w(3,2)*green(i+1,j)+w(3,3)*green(i+1,j+1);
green_f=sort(green_f);
I(i,j)= green_f(5);
blue_f(i,j)=w(1,1)*blue(i-1,j-1)+w(1,2)*blue(i-1,j)+w(1,3)*blue(i-1,j+1)+w(2,1)*blue(i,j-1)+w(2,2)*blue(i,j)+w(2,3)*blue(i,j+1)+...
w(3,1)*blue(i+1,j-1)+w(3,2)*blue(i+1,j)+w(3,3)*blue(i+1,j+1);
blue_f=sort(blue_f);
I(i,j)= blue_f(5);
end
end
final=cat(3,red_f,green_f,blue_f);
figure;
imshow(uint(w));
title('phonebox noisy');
figure;
imshow(uint8(final));
title('phonebox');

DGM on 22 Jan 2022
I don't know why you're using a weighting array that doesn't exist, but since you say this is a median filter, I'm going to assume you want a plain median filter.
I = imnoise(I,'salt & pepper');
[row, col, channels] = size(I); % dim() is a function
[red green blue] = imsplit(I);
output = zeros(size(I),class(I));
for i = 2:1:row-1
for j = 2:1:col-1
% if you want to do a median, i don't know why you're using a weighting filter
red_f = red(i-1:i+1,j-1:j+1);
red_f = sort(red_f(:));
output(i,j,1) = red_f(5); % you need to actually write to the output array
% of course, you can just use median() instead.
output(i,j,2) = median(green(i-1:i+1,j-1:j+1),'all');
output(i,j,3) = median(blue(i-1:i+1,j-1:j+1),'all');
% or you can just use a third loop
end
end
imshow(I);
title('phonebox noisy'); figure;
imshow(output);
title('phonebox'); DGM on 23 Jan 2022
This would be a start. This pulls the filter size out as a parameter
I = imnoise(I,'salt & pepper');
fs = [5 5];
[rows, cols, channels] = size(I);
pw = floor(fs/2);
output = I;
for rr = 1+pw(1):1:rows-pw(1)
for cc = 1+pw(2):1:cols-pw(2)
sample = I(rr-pw(1):rr+pw(1),cc-pw(2):cc+pw(2),:);
for c = 1:channels
output(rr,cc,c) = median(sample(:,:,c),'all');
end
end
end
imshow(output) Note that the approach you were using avoids indexing outside the array boundaries by restricting the region over which the filter actually processes the image. Normally, I'd do this by padding the image instead. This is another example that uses padding, but isn't adapted for multichannel images: