-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvanherk.m
177 lines (162 loc) · 4.73 KB
/
vanherk.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
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
function Y = vanherk(X,N,TYPE,varargin)
% VANHERK Fast max/min 1D filter
%
% Y = VANHERK(X,N,TYPE) performs the 1D max/min filtering of the row
% vector X using a N-length filter.
% The filtering type is defined by TYPE = 'max' or 'min'. This function
% uses the van Herk algorithm for min/max filters that demands only 3
% min/max calculations per element, independently of the filter size.
%
% If X is a 2D matrix, each row will be filtered separately.
%
% Y = VANHERK(...,'col') performs the filtering on the columns of X.
%
% Y = VANHERK(...,'shape') returns the subset of the filtering specified
% by 'shape' :
% 'full' - Returns the full filtering result,
% 'same' - (default) Returns the central filter area that is the
% same size as X,
% 'valid' - Returns only the area where no filter elements are outside
% the image.
%
% X can be uint8 or double. If X is uint8 the processing is quite faster, so
% dont't use X as double, unless it is really necessary.
%
% Initialization
[direc, shape] = parse_inputs(varargin{:});
if strcmp(direc,'col')
X = X';
end
if strcmp(TYPE,'max')
maxfilt = 1;
elseif strcmp(TYPE,'min')
maxfilt = 0;
else
error([ 'TYPE must be ' char(39) 'max' char(39) ' or ' char(39) 'min' char(39) '.'])
end
% Correcting X size
fixsize = 0;
addel = 0;
if mod(size(X,2),N) ~= 0
fixsize = 1;
addel = N-mod(size(X,2),N);
if maxfilt
f = [ X zeros(size(X,1), addel) ];
else
f = [X repmat(X(:,end),1,addel)];
end
else
f = X;
end
lf = size(f,2);
lx = size(X,2);
clear X
% Declaring aux. mat.
g = f;
h = g;
% Filling g & h (aux. mat.)
ig = 1:N:size(f,2);
ih = ig + N - 1;
g(:,ig) = f(:,ig);
h(:,ih) = f(:,ih);
if maxfilt
for i = 2 : N
igold = ig;
ihold = ih;
ig = ig + 1;
ih = ih - 1;
g(:,ig) = max(f(:,ig),g(:,igold));
h(:,ih) = max(f(:,ih),h(:,ihold));
end
else
for i = 2 : N
igold = ig;
ihold = ih;
ig = ig + 1;
ih = ih - 1;
g(:,ig) = min(f(:,ig),g(:,igold));
h(:,ih) = min(f(:,ih),h(:,ihold));
end
end
clear f
% Comparing g & h
if strcmp(shape,'full')
ig = [ N : 1 : lf ];
ih = [ 1 : 1 : lf-N+1 ];
if fixsize
if maxfilt
Y = [ g(:,1:N-1) max(g(:,ig), h(:,ih)) h(:,end-N+2:end-addel) ];
else
Y = [ g(:,1:N-1) min(g(:,ig), h(:,ih)) h(:,end-N+2:end-addel) ];
end
else
if maxfilt
Y = [ g(:,1:N-1) max(g(:,ig), h(:,ih)) h(:,end-N+2:end) ];
else
Y = [ g(:,1:N-1) min(g(:,ig), h(:,ih)) h(:,end-N+2:end) ];
end
end
elseif strcmp(shape,'same')
if fixsize
if addel > (N-1)/2
% disp('hoi')
ig = [ N : 1 : lf - addel + floor((N-1)/2) ];
ih = [ 1 : 1 : lf-N+1 - addel + floor((N-1)/2)];
if maxfilt
Y = [ g(:,1+ceil((N-1)/2):N-1) max(g(:,ig), h(:,ih)) ];
else
Y = [ g(:,1+ceil((N-1)/2):N-1) min(g(:,ig), h(:,ih)) ];
end
else
ig = [ N : 1 : lf ];
ih = [ 1 : 1 : lf-N+1 ];
if maxfilt
Y = [ g(:,1+ceil((N-1)/2):N-1) max(g(:,ig), h(:,ih)) h(:,lf-N+2:lf-N+1+floor((N-1)/2)-addel) ];
else
Y = [ g(:,1+ceil((N-1)/2):N-1) min(g(:,ig), h(:,ih)) h(:,lf-N+2:lf-N+1+floor((N-1)/2)-addel) ];
end
end
else % not fixsize (addel=0, lf=lx)
ig = [ N : 1 : lx ];
ih = [ 1 : 1 : lx-N+1 ];
if maxfilt
Y = [ g(:,N-ceil((N-1)/2):N-1) max( g(:,ig), h(:,ih) ) h(:,lx-N+2:lx-N+1+floor((N-1)/2)) ];
else
Y = [ g(:,N-ceil((N-1)/2):N-1) min( g(:,ig), h(:,ih) ) h(:,lx-N+2:lx-N+1+floor((N-1)/2)) ];
end
end
elseif strcmp(shape,'valid')
ig = [ N : 1 : lx];
ih = [ 1 : 1: lx-N+1];
if maxfilt
Y = [ max( g(:,ig), h(:,ih) ) ];
else
Y = [ min( g(:,ig), h(:,ih) ) ];
end
end
if strcmp(direc,'col')
Y = Y';
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [direc, shape] = parse_inputs(varargin)
direc = 'lin';
shape = 'same';
flag = [0 0]; % [dir shape]
for i = 1 : nargin
t = varargin{i};
if strcmp(t,'col') & flag(1) == 0
direc = 'col';
flag(1) = 1;
elseif strcmp(t,'full') & flag(2) == 0
shape = 'full';
flag(2) = 1;
elseif strcmp(t,'same') & flag(2) == 0
shape = 'same';
flag(2) = 1;
elseif strcmp(t,'valid') & flag(2) == 0
shape = 'valid';
flag(2) = 1;
else
error(['Too many / Unkown parameter : ' t ])
end
end