Создание «дырявого» медианного фильтра в Matlab - PullRequest
3 голосов
/ 18 ноября 2009

Что мне нужно сделать, так это создать «специальный» медианный фильтр для обработки изображений в Matlab - «дырявый» медианный фильтр. Это фильтр, который исключает элемент в центре области.

Для стандартного медианного фильтра я использую функцию medfilt2, но не могу передать маску (ядро) для нее как матрицу (это не линейное преобразование).
Например, используя стандартный фильтр усреднения 3x3, я создаю маску (ядро) как:

h = ones(3,3)/9;

А для усредняющего фильтра "дырявый":

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

Как сделать то же самое с медианным фильтром? Есть ли какой-нибудь способ изменить medfilt2 или мне нужно самостоятельно реализовать работающую медиану?

Ответы [ 3 ]

4 голосов
/ 18 ноября 2009

Как насчет использования базовой функции ordfilt2 и определения там своего собственного домена?

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

3 голосов
/ 18 ноября 2009

Используя идею @ Doug , ниже приведен пример, который обрабатывает все случаи:

  • положение отверстия в четном / нечетном размере маски
  • среднее положение в четном / нечетном количестве элементов

Пример:

%%# 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') );
0 голосов
/ 18 ноября 2009

Я предполагаю, что он не существует, и что вам нужно реализовать его самостоятельно. Вы можете написать один как функцию Matlab или, если скорость является проблемой, напишите один в C.

Еще один способ решить вашу проблему - использовать фильтр ранга . Это не то же самое, что вы просите, но может быть и другим способом достижения того, чего вы хотите.

...