-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfun_RIDGE_ORIENTATION.m
68 lines (54 loc) · 2.68 KB
/
fun_RIDGE_ORIENTATION.m
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
function [orientim, reliability] = fun_RIDGE_ORIENTATION(im, gradientsigma, blocksigma, orientsmoothsigma)
%
% Konark Jain
% Detect Local Ridge Orientation
%
[rows,cols] = size(im);
% Calculate image gradients.
sze = fix(6*gradientsigma); if ~mod(sze,2); sze = sze+1; end
f = fspecial('gaussian', sze, gradientsigma); % Generate Gaussian filter.
[fx,fy] = gradient(f); % Gradient of Gausian.
Gx = filter2(fx, im); % Gradient of the image in x
Gy = filter2(fy, im); % ... and y
%show(Gx+Gy,'Gradient');
% Estimate the local ridge orientation at each point by finding the
% principal axis of variation in the image gradients.
Gxx = Gx.^2; % Covariance data for the image gradients
Gxy = Gx.*Gy;
Gyy = Gy.^2;
% Now smooth the covariance data to perform a weighted summation of the
% data.
sze = fix(6*blocksigma); if ~mod(sze,2); sze = sze+1; end
f = fspecial('gaussian', sze, blocksigma);
Gxx = filter2(f, Gxx);
Gxy = 2*filter2(f, Gxy);
Gyy = filter2(f, Gyy);
% Analytic solution of principal direction
denom = sqrt(Gxy.^2 + (Gxx - Gyy).^2) + eps;
sin2theta = Gxy./denom; % Sine and cosine of doubled angles
cos2theta = (Gxx-Gyy)./denom;
sze = fix(6*orientsmoothsigma); if ~mod(sze,2); sze = sze+1; end
f = fspecial('gaussian', sze, orientsmoothsigma);
cos2theta = filter2(f, cos2theta); % Smoothed sine and cosine of
sin2theta = filter2(f, sin2theta); % doubled angles
orientim = pi/2 + atan2(sin2theta,cos2theta)/2;
% Calculate 'reliability' of orientation data. Here we calculate the
% area moment of inertia about the orientation axis found (this will
% be the minimum inertia) and an axis perpendicular (which will be
% the maximum inertia). The reliability measure is given by
% 1.0-min_inertia/max_inertia. The reasoning being that if the ratio
% of the minimum to maximum inertia is close to one we have little
% orientation information.
Imin = (Gyy+Gxx)/2 - (Gxx-Gyy).*cos2theta/2 - Gxy.*sin2theta/2;
Imax = Gyy+Gxx - Imin;
reliability = 1 - Imin./(Imax+.001);
% Finally mask reliability to exclude regions where the denominator
% in the orientation calculation above was small. Here I have set
% the value to 0.001, adjust this if you feel the need
reliability = reliability.*(denom>.001);
% figure, imshow(255-uint8(im)); hold on;
% x = downsample(downsample(orientim,16)',16)';
% u = 0.01*cos(x);
% v = 0.01*sin(x);
% q = quiver(1:16:size(orientim,2), 1:16:size(orientim,1), u, v, '-');
% hold off;