Gacek
Gacek

Reputation: 10312

Creating "holey" median filter in Matlab

What I need to do is to create a "special" kind of median filter for image processing in Matlab - the "holey" median filter. This is a filter that excludes the element at the center of the area.

For standard median filter I use the medfilt2 function, but I can't pass the mask (kernel) for it as a matrix (it's not a linear transform).
For example, using standard averaging filter 3x3 I create the mask (kernel) as:

h = ones(3,3)/9;

And for "holey" averaging filter:

h = ones(3,3)/8;
h(2,2) = 0;

How to do the same thing with median filter? Is there any way to modify the medfilt2 or do I need to implement a running median on my own?

Upvotes: 3

Views: 2447

Answers (3)

MatlabDoug
MatlabDoug

Reputation: 5714

What about using the underlying function ordfilt2 and defining your own domain there?

https://www.mathworks.com/help/images/ref/ordfilt2.html

Upvotes: 4

Amro
Amro

Reputation: 124563

Using @Doug's idea, the following is an example that handles all cases:

  • hole position in even/odd mask size
  • median position in even/odd number of elements

Example:

%%# mask size: N-by-N
N = 3;
assert(N>=3);

%%# read image and add noise
I = im2double( imread('eight.tif') );
I = imnoise(I, 'salt & pepper',0.05);

%%# build mask with hole in center
h = true(N,N);
if mod(N,2) == 0
    %# hole is a 2-by-2 square
    h([N/2 N/2+1],[N/2 N/2+1]) = false(2);
else
    %# hole is one point
    h((N+1)/2,(N+1)/2) = false;
end

%%# compute median filter with hole
num = sum(h(:));
if mod(num,2) == 0
    %# even case: average from using the two elements in the middle
    I1 = ordfilt2(I, num/2, h, 'symmetric');
    I2 = ordfilt2(I, num/2+1, h, 'symmetric');
    J = imdivide( imadd(I1,I2), 2 );
else
    %# odd case: note this is never reached
    J = ordfilt2(I, (num+1)/2, h, 'symmetric');
end

%%# plot and compare against normal median filter
subplot(121), imshow(J)
subplot(122), imshow( medfilt2(I,[N N],'symmetric') );

Upvotes: 3

Phillip Ngan
Phillip Ngan

Reputation: 16106

My guess is that it does not exist, and that you would need to implement one yourself. You can write one as a matlab function or if speed is an issue, write one in C.

Another way to approach your problem is to use a rank filter. It is not the same as what you are asking for, but might be another way to achieve what you want.

Upvotes: 0

Related Questions