Search code examples
matlabimage-processingmediannoise-reduction

How to implement median filter with a kernel in MATLAB to smooth an image?


I don't know how to implement a median filter with a sliding window (kernel) in MATLAB. I need to know how the implementation looks like so I can try to implement a BSE algorithm (block smart erase), which is very similar to the median filter. I need that to erase some black and white pixels. I know that there's the medfilt2() function but I need to know how it is implemented.

The BSE algorithm works like this:

The BSE algorithm is based on median technology and takes the place of the extreme value (black or white) pixel by the median value of their surrounding pixels.

1) For an NxN window centered at the test pixel, where N would normally be and larger value should be suggested.

2) If f(i,j) = 0 or f(i,j) = 255, f(i,j) is an absolute extreme value pixel that must be estimated; go to step 3. Otherwise, the value of f(i,j) is not altered; go to step 4.

3) When an extreme value pixel is detected, its gray level is substituted by the median value of the window.

4) The procedure is repeated for the next window.

What I understood was that I need to implement the median filter with a condition to check if the current pixel value is 0 or 255. If it is, I change that value for the median value of its neighbourhood pixels.

I dont know if I was clear enough but I need some help with that:).

Current BSE algorithm:

function [outimg] = medianfilt(img,sz)
green  = img(:,:,2);
[rows,cols] = size(green);    % get size of grayscale image
pad = sz-1; % padding to be added
nimg = zeros(rows+pad,cols+pad); % padded image
nimg(pad/2+1:rows+pad/2, pad/2+1:cols+pad/2) = green;
outimg = zeros(rows,cols);  % output / median filtered image
for x = pad/2 + 1 : cols + pad/2  % loop over columns
    for y = pad/2 + 1 : rows + pad/2   % loop over rows
        if nimg(y,x) == 0 || nimg(y,x) == 255
            win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
            outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
        else
            outimg(y-pad/2,x-pad/2) = nimg(y,x);
        end
        win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
        outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
    end
end
imshow(outimg);
end

Solution

  • you can implement median filter as below:

    function [outimg] = medianfilt(img,sz)
        [rows,cols] = size(img);    % get size of grayscale image
        pad = sz-1; % padding to be added
        nimg = zeros(rows+pad,cols+pad); % padded image
        nimg(pad/2+1:rows+pad/2, pad/2+1:cols+pad/2) = img;
        outimg = zeros(rows,cols);  % output / median filtered image
        for x = pad/2 + 1 : cols + pad/2  % loop over columns
            for y = pad/2 + 1 : rows + pad/2   % loop over rows 
                win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
                outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
            end
        end
    end
    

    you can check for BSE as below:

    if nimg(y,x) == 0 || nimg(y,x) == 255
        win = nimg(y-pad/2:y+pad/2, x-pad/2:x+pad/2);  % get mxm window
        outimg(y-pad/2,x-pad/2) = median(win(:));      % find median
    else
        outimg(y-pad/2,x-pad/2) = nimg(y,x);
    end