Я хочу реализовать двумерный согласованный фильтр для извлечения кровеносных сосудов в соответствии со статьей «Обнаружение кровеносных сосудов на изображениях сетчатки с использованием двумерных согласованных фильтров» Чаудхури и др., IEEE Trans.по медицинской визуализации, 1989 г. ( есть PDF на веб-сайте автора ).
Краткое описание: поперечное сечение кровеносного сосуда имеет гауссовское распределение, и поэтому я хочу использовать гауссовское соответствиефильтр для увеличения SNR.Такое ядро может быть математически выражено как:
K(x,y) = -exp(-x^2/2*sigma^2) for |x|<3*sigma, |y|<L/2
L
здесь - длина судна с фиксированной ориентацией.Экспериментально sigma=1.5
и L = 7
.
Мой код MATLAB для этой части:
s = 1.5; %sigma
t = -3*s:3*s;
theta=0:15:165; %different rotations
%one dimensional kernel
x = 1/sqrt(6*s)*exp(-t.^2/(2*s.^2));
L=7;
%two dimensional gaussian kernel
x2 = repmat(x,L,1);
Рассмотрим реакцию этого фильтра для пикселя, принадлежащего фоновой сетчатке.Предполагая, что фон имеет постоянную интенсивность с нулевым средним аддитивным гауссовским белым шумом, ожидаемое значение выходного сигнала фильтра в идеале должно быть равно нулю.Поэтому ядро свертки модифицируется путем вычитания среднего значения s(t)
из самой функции.Среднее значение ядра определяется следующим образом: m = Sum(K(x,y))/(number of points)
.
Таким образом, сверточная маска, используемая в этом алгоритме, определяется следующим образом: K(x, y) = K(x,y) - m
.
Мой код MATLAB:
m = sum(x2(:))/(size(x2,1)*size(x2,2));
x2 = x2-m;
Судно может быть ориентировано под любым углом 0<theta<180
, и согласованный отклик фильтра максимален, когда он выровнен по theta+- 90
(распределение поперечного сечения по Гауссу, а не само судно).
Таким образом, нам нужно повернуть согласованный фильтр 12 раз с шагом 15 градусов.
Мой код MATLAB прилагается, но я не получаю желаемого результата.Любая помощь приветствуется.
%apply rotated matched filter on image
r = {};
for k = 1:12
x3=imrotate(x2,theta(k),'crop');%figure;imagesc(x3);colormap gray;
r{k}=conv2(img,x3);
end
w=[];h = zeros(584,565);
for i = 1:565
for j = 1:584
for k = 1:32
w= [w ,r{k}(j,i)];
end
h(j,i)=max(abs(w));
w = [];
end
end
%show result
figure('Name','after matched filter');imagesc(h);colormap gray
Для вращения я использовал imrotate
, что мне кажется более разумным, но в статье все иначе: предположим, p=[x,y]
будет дискретной точкой в ядре.Для вычисления коэффициентов в повернутом ядре у нас есть [u,v] = p*Rotation_Matrix
.
Rotation_Matrix=[cos(theta),sin(theta);-sin(theta),cos(theta)]
И ядро:
K(x,y) = -exp(-u^2/2*s^2)
Но новое ядро больше не имеет гауссовой формы.Использование imrotate
сохраняет гауссову форму.Так в чем же преимущество использования матрицы вращения?
Входное изображение:
Выход:
Согласованная фильтрация помогает увеличить SNR, но также усиливается фоновый шум.Правильно ли я использую imrotate
для вращения ядра?Моя главная проблема с матрицей вращения, почему и каков правильный код для ее реализации.