-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathFindlclmxm.m
83 lines (68 loc) · 3.15 KB
/
Findlclmxm.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
function [ row, clmn, rowSPA, clmnSPA, MxMtr ] = Findlclmxm( Mtr, NBHOOD, BorderDistance, ThreshType, HarrisThresh )
% Function receives inputs 'Mtr' - matrix of scalar values, NBHOOD -
% information about how to define local region/neighborhood.
% In case if NBHOOD is scalar, then as neighborhood will be taken circle/disk
% with radius = NBHOOD.
% Otherwise NBHOOD will be a matrix which define neighborhood for looking for
% maximum in this region ( with 0 and 1 ).
% 'row', 'clmn' - row and column vectors of local maximums, 'MxMtr' -
% matrix of the same dimension as Mtr, but all elements 0, except elements
% [ row, clmn ], they have the same value in those positions as in Mtr.
% If finded maximums near border at distance less then BorderDistance, then
% it'll be illuminated, also maximums values will be threshed./ BorderDistance can be matrix with ones and zeros /
% Also it returns approximation of place (columns, row) of local maximums.
[ m, n ] = size( Mtr );
if isscalar(BorderDistance)
Tmp = zeros(size(Mtr));
Tmp( (BorderDistance + 1):(m - BorderDistance), (BorderDistance + 1):(n - BorderDistance) ) = 1;
else
Tmp = BorderDistance;
end
MtrTmp = Mtr;
Mtr = Mtr.*Tmp;
MxMtr = zeros(size(Mtr));
% calculate system of neighboors pixels
if isscalar(NBHOOD)
NBHOOD = fspecial('disk', NBHOOD) > 0;
N = sum(NBHOOD(:));
else
N = sum(NBHOOD(:));
end
local_mxm = ordfilt2( Mtr, N, NBHOOD );
local_second_value = ordfilt2( Mtr, N-1, NBHOOD );
%------------------- Find thresh ---------------------%
switch ThreshType
case 'percent'
T = HarrisThresh*max(local_mxm(:));
case 'const'
T = HarrisThresh;
end
% indexes of strict local maximums, threshed and filterd for distance from
% borders
ind = find( (Mtr == local_mxm) & (local_second_value ~= local_mxm) & ( Mtr >= T ) );
% MxMtr(ind) = Mtr(ind);
ind = ind(:);
%[ row, clmn ] = ind2sub( [ m, n ], ind );
% defining sub-pixel accuracy
%----------------- Derivative masks ------------------%
dFdx = [ 0 0 0; -1 0 1; 0 0 0];
dFdy = [ 0 -1 0; 0 0 0; 0 1 0 ];
d2Fdx2 = [ 0 0 0; 1 -2 1; 0 0 0 ];
d2Fdy2 = [ 0 1 0; 0 -2 0; 0 1 0 ];
d2Fdxdy = [ 1 0 -1; 0 0 0; -1 0 -1 ]/4;
%-------------------- Derivatives ---------------------%
Fx = imfilter( MtrTmp, dFdx, 'same' );
Fy = imfilter( MtrTmp, dFdy, 'same' );
Fxx = imfilter( MtrTmp, d2Fdx2, 'same' );
Fyy = imfilter( MtrTmp, d2Fdy2, 'same' );
Fxy = imfilter( MtrTmp, d2Fdxdy, 'same' );
%----------- Column sub-pixel accuracy (SPA) ----------%
% formula is taken from MOP paper ( multiscale oriented patches )
ind = ind(( Fxx(ind).*Fyy(ind)-(Fxy(ind)).^2 ) ~= 0);
ClmnDeltaX = (Fx(ind).*Fyy(ind)-Fxy(ind).*Fy(ind))./( Fxx(ind).*Fyy(ind)-(Fxy(ind)).^2 );
%-------------- Row sub-pixel accuracy ----------------%
RowDeltaY = (Fy(ind).*Fxx(ind)-Fxy(ind).*Fx(ind))./( Fxx(ind).*Fyy(ind)-(Fxy(ind)).^2 );
%---- Removing pixels, that can't be approximated -----%
ind2 = find( abs(RowDeltaY)<= 1 & abs(ClmnDeltaX)<= 1 );
ind = ind( ind2 ); [ row, clmn ] = ind2sub( [ m, n ], ind );
rowSPA = row - RowDeltaY( ind2 ); clmnSPA = clmn - ClmnDeltaX( ind2 ); MxMtr(ind) = Mtr(ind);