-
Notifications
You must be signed in to change notification settings - Fork 0
/
FrangiFilter2D
120 lines (105 loc) · 3.76 KB
/
FrangiFilter2D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function [outIm,whatScale,Direction] = FrangiFilter2D(I, options)
% This function FRANGIFILTER2D uses the eigenvectors of the Hessian to
% compute the likeliness of an image region to vessels, according
% to the method described by Frangi:2001 (Chapter 2).
%
% [J,Scale,Direction] = FrangiFilter2D(I, Options)
%
% inputs,
% I : The input image (vessel image)
% Options : Struct with input options,
% .FrangiScaleRange : The range of sigmas used, default [1 8]
% .FrangiScaleRatio : Step size between sigmas, default 2
% .FrangiBetaOne : Frangi correction constant, default 0.5
% .FrangiBetaTwo : Frangi correction constant, default 15
% .BlackWhite : Detect black ridges (default) set to true, for
% white ridges set to false.
% .verbose : Show debug information, default true
%
% outputs,
% J : The vessel enhanced image (pixel is the maximum found in all scales)
% Scale : Matrix with the scales on which the maximum intensity
% of every pixel is found
% Direction : Matrix with directions (angles) of pixels (from minor eigenvector)
%
% Example,
% I=double(imread ('vessel.png'));
% Ivessel=FrangiFilter2D(I);
% figure,
% subplot(1,2,1), imshow(I,[]);
% subplot(1,2,2), imshow(Ivessel,[0 0.25]);
%
% Written by Marc Schrijver, 2/11/2001
% Re-Written by D.Kroon University of Twente (May 2009)
defaultoptions = struct('FrangiScaleRange', [1 10], 'FrangiScaleRatio', 2, 'FrangiBetaOne', 0.5, 'FrangiBetaTwo', 15, 'verbose',true,'BlackWhite',true);
% Process inputs
if(~exist('options','var')),
options=defaultoptions;
else
tags = fieldnames(defaultoptions);
for i=1:length(tags)
if(~isfield(options,tags{i})), options.(tags{i})=defaultoptions.(tags{i}); end
end
if(length(tags)~=length(fieldnames(options)))
warning('FrangiFilter2D:unknownoption','unknown options found');
end
end
sigmas=options.FrangiScaleRange(1):options.FrangiScaleRatio:options.FrangiScaleRange(2);
sigmas = sort(sigmas, 'ascend');
beta = 2*options.FrangiBetaOne^2;
c = 2*options.FrangiBetaTwo^2;
% Make matrices to store all filterd images
ALLfiltered=zeros([size(I) length(sigmas)]);
ALLangles=zeros([size(I) length(sigmas)]);
% Frangi filter for all sigmas
for i = 1:length(sigmas)
% Show progress
if(options.verbose)
disp(['Current Frangi Filter Sigma: ' num2str(sigmas(i)) ]);
end
% Make 2D hessian
[Dxx,Dxy,Dyy] = Hessian2D(I,sigmas(i));
% Correct for scale
Dxx = (sigmas(i)^2)*Dxx;
Dxy = (sigmas(i)^2)*Dxy;
Dyy = (sigmas(i)^2)*Dyy;
% Calculate (abs sorted) eigenvalues and vectors
[Lambda2,Lambda1,Ix,Iy]=eig2image(Dxx,Dxy,Dyy);
% Compute the direction of the minor eigenvector
angles = atan2(Ix,Iy);
% Compute some similarity measures
Lambda1(Lambda1==0) = eps;
Rb = (Lambda2./Lambda1).^2;
S2 = Lambda1.^2 + Lambda2.^2;
% Compute the output image
Ifiltered = exp(-Rb/beta) .*(ones(size(I))-exp(-S2/c));
% see pp. 45
if(options.BlackWhite)
Ifiltered(Lambda1<0)=0;
else
Ifiltered(Lambda1>0)=0;
end
% store the results in 3D matrices
ALLfiltered(:,:,i) = Ifiltered;
ALLangles(:,:,i) = angles;
end
% Return for every pixel the value of the scale(sigma) with the maximum
% output pixel value
if length(sigmas) > 1
[outIm,whatScale] = max(ALLfiltered,[],3);
outIm = reshape(outIm,size(I));
if(nargout>1)
whatScale = reshape(whatScale,size(I));
end
if(nargout>2)
Direction = reshape(ALLangles((1:numel(I))'+(whatScale(:)-1)*numel(I)),size(I));
end
else
outIm = reshape(ALLfiltered,size(I));
if(nargout>1)
whatScale = ones(size(I));
end
if(nargout>2)
Direction = reshape(ALLangles,size(I));
end
end