-
Notifications
You must be signed in to change notification settings - Fork 5
/
rampsharp.m
646 lines (559 loc) · 22.5 KB
/
rampsharp.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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
%% RAMPSHARP - Iterative ramp sharpening of multispectral images.
%
%% Description
% Perform (multispectral) image enhancement through iterative local ramp
% sharpening as described in [GS10].
%
%% Syntax
% [SH,TR] = RAMPSHARP(I);
% [SH,TR] = RAMPSHARP(I, niter, method, sigma, rho);
% [SH,TR] = RAMPSHARP(I, niter, method, sigma, rho,
% 'Property', propertyvalue, ...);
%
%% Inputs
% *|I|* : input image with dimension |C|, possibly multispectral (|C>1| bands).
%
% *|niter: optional positive parameter setting the number of iterations of
% the sharpening algorithm; when |niter=0|, the sharpening is iterated
% till convergence; default: |niter=1|.
%
% *|method|* :
%
% *|sigma|* : pre-smoothing width (half-window size in pixels); this parameter
% sets the differentiation scale in the case the image is smoothed prior
% to the differentiation through Gaussian filtering; sigma typically
% controls the size of the objects whose orientation has to be estimated;
% default: |sigma=0.5|, i.e. Gaussian regularisation is used for estimating
% the derivatives.
%
% *|rho|* : post-smoothing width (half-window size in pixels); this parameter
% sets the integration scale for spatial averaging, that controls the
% size of the neighbourhood in which an orientation is dominant; it is
% used for averaging the partial directional derivatives of the tensor
% with a Gaussian kernel; if |rho<0.05|, then no smoothing is performed;
% default: |rho=0.5|.
%
% *|der|* : flag defining the original |(3,3)| gradient mask used for estimating
% the directional derivatives of the input image; it is either (see
% |GRADMASK|):
%
% * |'sob'| for Sobel mask,
% * |'dif'| for central differences,
% * |'for'| when forward differences are computed,
% * |'bac'| when backward differences are computed,
% * |'pre'| for Prewitt mask,
% * |'iso'| for Frei-Chen's isotropic mask,
% * |'opt'| for Ando's optimal mask,
% * |'cir'| for Davies' circular mask;
%
% default: |der='dif'|.
%
%% Property [propertyname propertyvalues]
% *|'pilot'|* :
%
% *|'alpha'|* : flag setting the correction factor alpha when updating a pixel
% value; the correction alpha is based on the estimated gradient indices
% $G_M$, $G_L$ and $G_H$ (see [Leu00]) for further definition of the gradient
% indices); therefore, alpha is expected to be either:
%
% * |'f0'| then $F = (G_1 - G_M) / (G_M - G_2)$ (following [Leu00]),
% * |'f1'| then $F = (G_2 + G_M) / (1 + 2*G_M)$, (default)
% * |'f2'| then $F = (G_1 + G_2 - G_M) / (1 + 3*G_M)$,
% * |'f3'| then $F = (G_1 + G_2) / (1 + 2*G_M)$,
% * |'f4'| then $F = (G_1 + G_M) / (1 + 2*G_M)$,
% * |'f5'| then $F = (G_1 + G_2 + G_M) / (1 + 3*G_M)$,
%
% where $G_1$ and $G_2$ stand for either $G_L$ or $G_H$, depending on which
% part of of the ramp (lower or higher) the pixel belongs to.
%
% *|'fE'|* : optional parameter setting the factor effect (see [Leu00]) as a
% multiplicative effect on the correction factor, so that:
% $F = F \cdot fE$.
%
% *|'win'|* : set the parameters of the local kernel windows used for estimating
% the local gradient and intensity indices
%
% * |'w0'| : the kernel weights are identical to those of Leu's approach,
% * |'w1'| : new kernel weights.
%
% *|'adjust'|* : 'shift' or 'control'
%
% *|'crit'|* : optional flag for deciding how vectorial components are taken
% into account in the ramp decision, depending on the estimated intensity
% indices $I_M$, $I_L$ and $I_H$ (see [Leu00]) for further definition of
% the intensity indices); it provides the adju for deciding when a (vector)
% pixel has to be considered as a ramp pixel - useful only when |C>1|;
% it is either:
%
% * 'all': then for each pixel, we check if it exists one band where its $I_H$
% is greater than its $I_M$ and its $I_M$ is greater than its $I_L$,
% and we verify that there is no band where its $I_H$ is lower than
% its $I_M$ or its $I_M$ is lower than its $I_L$, ie.:
% $$
% \exists i, I_H(i) > I_M(i) > I_L(i) \quad \& \quad
% \forall j \neq i, I_H(j) \geq I_M(j) \geq I_L(j)
% $$
%
% note that in the case |nc=1|, the previous condition is equivalent
% to that proposed in [Leu00],
%
% * 'one': it is enough that the relationship regarding neighbour pixels
% intensity is verified in one channel to perform the local
% adjustment, ie.:
% $$
% \exists i, I_H(i) > I_M(i) > I_L(i)
% $$
%
% (more flexible than the previous option in the multispectral
% case, equivalent in the monospectral one)
%
% *|'derive'|* :
%
% * |'grd'|
% * |'tens'|
%
% *|'sigma'|* :
%
% *|'rho'|* :
%
% *|'hsize'|* : optional filter size; default: estimated depending on |sigma|,
% typically |hsize=6*sigma+1|.
%
% *|'eigen'|* :
%
% *|samp|* : to perform |(*samp)| interpolation of the gradient to avoid aliasing.
%
%% Outputs
% *|SH|* :
%
% *|TR|* : transition map, where a positive graylevel intensity indicates the
% last iteration the pixel was detected as a transition
%
%% References
% [Leu00] J.G. Leu: "Edge sharpening through ramd width reduction", Image
% and Vision Computing, 18:501-514, 2000.
% <http://www.sciencedirect.com/science/article/pii/S0262885699000414>
%
% [GS10] J. Grazzini and P. Soille: "Iterative ramp sharpening for
% structure/signature-preserving simplification of images", Proc.
% ICPR, pp. 4586-4589, 2010.
% <http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5597348>
%% Function implementation
function [SH,TH,pl, pch] = rampsharp(I,varargin)
error(nargchk(1, 33, nargin, 'struct'));
error(nargoutchk(1, 4, nargout, 'struct'));
%%
% parsing parameters
if ~isnumeric(I)
error('rampsharp:errorinput','a matrix is required in input');
end
% Optional parameters
p = createParser('RAMPSHARP'); % create an instance of the inputParser class.
% mandatory (required) variables
%p.addRequired('I', @isnumeric);
% principal optional parameters
p.addOptional('niter', 1, @(x)isscalar(x) && x>=0);
p.addOptional('method', 'control', @(x)ischar(x) && ...
any(strcmpi(x,{'shift', 'leu', 'control'})));
p.addOptional('sigma', 0.5, @(x)isscalar(x) && isfloat(x) && x>=0);
p.addOptional('rho', 1, @(x)isscalar(x) && isfloat(x) && x>=0);
% other optional parameters
p.addOptional('der', 'fast', @(x)islogical(x) || (ischar(x) && ...
any(strcmpi(x,{'matlab','vista','fast','conv','fleck', ...
'tap5','tap7','sob','opt','ana'}))));
p.addOptional('int', 'fast', @(x)islogical(x) || (ischar(x) && ...
any(strcmpi(x,{'matlab','conv','fast','ani'}))));
p.addParamValue('hsize',5, @(x)isscalar(x));
p.addParamValue('samp', 1, @(x)isscalar(x) && round(x)==x && x>=1 && x<=5);
p.addParamValue('pilot', 'ave', @(x)ischar(x) && any(strcmpi(x,{'ave', 'int'})));
p.addParamValue('fac', 'f5', @(x)ischar(x) && ...
any(strcmpi(x,{'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'leu'})));
p.addParamValue('kern', 'leu', @(x)ischar(x) && ...
any(strcmpi(x,{'new', 'leu'})));
p.addParamValue('fE', 1, @(x)isscalar(x) && isfloat(x));
p.addParamValue('nz', 8, @(x)x==8 || x==16);
p.addParamValue('interp', 0, @(x)isscalar(x) && x>=1);
p.addParamValue('crit', 'all', @(x)ischar(x) && any(strcmpi(x,{'all', 'one'})));
p.addParamValue('eign', 'zen', @(x)ischar(x) && ...
any(strcmpi(x,{'abs','zen', 'sap','sum', 'dif', 'ndi'})));
p.addParamValue('gthres', 0, @(x)isscalar(x) && isfloat(x) && x>=0 && x<=1);
p.addParamValue('pctch', 0.01, @(x)isscalar(x) && isfloat(x) && x>=0 && x<=1);
p.addParamValue('trans', 'indice', @(x)ischar(x) && ...
any(strcmpi(x,{'indice', 'morph'})));
% parse and validate all input arguments
p.parse(varargin{:});
p = getvarParser(p);
% default choice parameters when the option 'method' has been set to 'leu',
% ie'. the original implementation of [Leu00] is to be ran.
if strcmp(p.method,'leu')
p.method = 'shift'; % just shift the value, without controlling its extent
p.kern = 'leu'; % original weights for computing the indices
p.der = 'sob'; % sobel gradient for estimating the derivatives
p.nz = '8'; % 8 zones to be used in interpolation of indices
p.fac = 'f0'; % factor used in shifting
p.crit = 'one'; % check only if assertion is true on single band
p.interp = 0; % no prior interpolation of input image
p.sigma = 0; % no smoothing
p.rho = 0; % no integration
p.fE = 1; % no correction factor
end
% switch p.der
% case 'pey'
% p.hsize = max(1+round(p.sigma)*2, 7);
% case {'rad','mat','kro'}
% p.hsize = ceil(4 * p.sigma); % approximation
% otherwise
% p.hsize = ceil(6 * p.sigma);
% end
%%
% internal variables
% check the dimension of the input image:
nbdims = nb_dims(I); % instead of ndims
if nbdims<2 || nbdims>3
error('matrix or array of matrices are expected as inputs');
end
% number of spectral components
Z = size(I,3);
% possibly overwrite
if Z~=3 && strcmp(p.pilot,'int')
warning('ramspharp:inputparameter',...
'pilot image as intensity implemented only for RGB images');
p.pilot = 'ave';
end
%%
% internal parameters (do not modify)
% Initializing variables
pchange = p.pctch +1;
% We adopt the following index representation for the directed components
% used for the intensity and gradient indices used (matlab indexing)
% --------------- -------------
% | NW | N | NE | | 1 | 4 | 7 |
% --------------- -------------
% | W | | E | => | 2 | 5 | 8 |
% --------------- -------------
% | SW | S | SE | | 3 | 6 | 9 |
% --------------- -------------
direction_indices = struct('east', 8, 'northeast', 7, 'north', 4, ...
'northwest', 1, 'west', 2, 'southwest', 3, ...
'south', 6, 'southeast', 9, 'central', 5); %#ok
%directions = fieldnames(direction_indices);
%ndirections = length(directions);
% note: not used in the following
level_indices = struct( 'L', 1, 'M', 2, 'H', 3);
L = level_indices.('L'); M = level_indices.('M'); H = level_indices.('H');
% Remember: mapping from indexes to subscripts for a 3x3 matrix in matlab
% ------------------- -------------
% | 1,1 | 1,2 | 1,3 | | 1 | 4 | 7 |
% ------------------- -------------
% | 2,1 | 2,2 | 2,3 | => | 2 | 5 | 8 |
% ------------------- -------------
% | 3,1 | 3,2 | 3,3 | | 3 | 6 | 9 |
% ------------------- -------------
% (ii,jj) => ii+3*(jj-1)
%% construct beforehand the predefined local 3x3 kernels defined for each
% different zone and level, and used for the estimation of the gradient and
% intensity indices (used once at the beginning of the code).
% Intensity and gradient masks are built for both zones 1 and 2, and all
% the other zones derived by rotation
switch p.kern
case 'leu'
matI = local3x3kernel('ker','i0','norm',true);
matG = local3x3kernel('ker','g0','norm',true);
case 'new'
matI = local3x3kernel('ker','i1','norm',true);
matG = local3x3kernel('ker','g1','norm',true);
end
% mote: matI and matG are indexed by [size(x,y),zone,level]
%%
% main computation through iterative filtering
% possibly resize the input matrix
if p.interp
A = upscalexy(I,[2 2],'cubic');
else
A = I;
end
% initialize the output matrix
% SH = A;
% dimension of the frame
[X,Y] = size(A(:,:,1));
XY = X * Y; % numel(A(:,:,1));
% index of all pixels in the input image
% pixindex = reshape(1:XY,[X Y]);
% indexes of the border pixels
% pixbord = [1:X, (1:Y-2)*X+1, (2:Y-1)*X, (1+X*(Y-1)):XY]';
% create the 'pilot' for gradient orientation
if Z==3 && strcmp(p.pilot,'bright')
p.pilot = rgb2gray(A); % pilot will be the brightness image
elseif Z>=2
p.pilot = sum(A,3) / Z; % pilot will be the average image
end
% construct the variation sparse matrices measuring the amount of change
% occurring in the image after each of the iterative filtering
deltaI = zeros(XY,Z);
dirdeltaI = deltaI;
% index of transition pixels for each step of the iterations
Itrans = cell(p.niter);
% set the number of estimated gradient
nZ = Z + (Z>1); % ie: ng=1 if Z==1, ng=Z+1 otherwise
G = zeros(X,Y,nZ);
pl = A(110, :);
pch = [];
TH = zeros(X,Y);
%%
% proceed iteratively
for iter=1:p.niter
% A = smoothfilt(A, p.sigma, 'sm', p.sm, 'hsize',p.hsize);
% estimation of the structure tensor (see function GSTSMOOTH)
% compute the gradient (gy: vertical, gx: horizontal) for each channel
% hsize = max(1+round(p.sigma)*2, 7);
% [gy,gx,G(:,:,1:Z)] = grdsmooth(I,p.sigma,'hsize',hsize,...
% 'der','peyre', 'axis', 'xy');
% gy = -gy;
%same as first compute: [gx,gy]=grdsmooth(I,sigma,'der',der,'hsize',hsize);
%and then take the vector orthogonal to the gradient: tmp=gx; gx=gy; gy=-tmp;
% /|\
% gy |
% at that point: |
% ------> gx
% note that the output directional derivatives have size [X Y Z]
% estimation of the gradient structure tensor
% [gx2,gy2,gxy,G(:,:,nZ),Theta] = grd2gst(gx, gy, p.rho, ...
% 'int', 'peyre', 'axis', 'hv', 'eign','zenzo');
[T,gx,gy] = gstsmooth(A,p.rho,p.sigma,'der',p.der, 'int', p.int, ...
'hsize',p.hsize,'samp', p.samp);
% norm and orientation are extracted features
if p.rho>eps
theta = mod(atan2(mean(gy,3),mean(gx,3)),pi);
gx = smoothfilt( gx, p.rho, 'sm', p.int, 'theta', theta, ... % or Theta?
'hsize',p.hsize,'samp', p.samp );
gy = smoothfilt( gy, p.rho, 'sm', p.int, 'theta', theta, ...
'hsize',p.hsize,'samp', p.samp );
end
if Z>1
% norm channel by channel
G(:,:,1:Z) = sqrt(gx.^2 + gy.^2);
% update the value of the gradient to set it to the gradient of
% the average image
gx = sum(gx,3) / Z;
gy = sum(gy,3) / Z;
end
%%
% estimation of the orientation of the ramp sharpening
% reroriented tensor taking into account the average gradient
Theta = gstfeature(T(:,:,1,1), T(:,:,2,2), T(:,:,1,2), 'orvec', ...
'ex', gx, 'ey', gy);
size(Theta)
figure, imagesc(rescale(Theta))
%Theta=theta;
T = gstdecomp(T, Theta);
% figure, imagesc(Theta),colormap jet, axis image, title('theta')
% tensorial norm
[G(:,:,nZ), C] = gstfeature(T(:,:,1,1), T(:,:,2,2), T(:,:,1,2), ...
['eigenorm' 'coherence'], 'eign', p.eign);
max(G(:))
% find the orientation and the interpolation parameters over the image
[Zones,Omega] = localorientzone(Theta,p.nz);
% compute the compensation factor
S = 1 - (1-sqrt(2.)) * Omega;
%%
% local estimation of intensity indices
% prior computation of the intensity indices over the different
% spectral components
mI = localorientfeature(A, 'filt', 'mean', ... % 'filt','med'
'Kernel',matI,'Zones',Zones,'Omega',Omega);
% mI = round(mI);
%%
% local estimation and characterization of ramp/transition pixels
Iramp = maptransition(mI,p.trans,'const','strong');
figure, imagesc(reshape(Iramp,[X,Y]));
% get rid of flat area:
if p.gthres > 0
m = max(max(G(:,:,nZ)));
else
m=0;
end
Iramp = Iramp & reshape(G(:,:,nZ),[XY 1])>m*p.gthres;
% if no consideration for this condition: Iramp = ones(XY,1);
%figure, imagesc(reshape(Iramp(:,:,1),X,Y)), axis image, colormap gray;
Iramp = find(Iramp);
% proceed only if such pixels have been found
if isempty(Iramp) % this is very improbable
break;
end
%%
% local estimation of the gradient indices
%mG = zeros(lenght(Iramp), nelevels, Z);
mG = localorientfeature(G,'filt','mean', ...
'Kernel',matG,'Zones',Zones,'Omega',Omega);
% reduce the problem to potential ramp pixels: restrict the set of
% pixels which are examined to pixels on the ramp
mI = mI(Iramp,:,:);
mG = mG(Iramp,:,:);
if strcmp(p.method,'control')
D = deltaI(Iramp,:);
ID = dirdeltaI(Iramp,:);
else
D = zeros(length(Iramp),Z);
ID = [];
end
S = S(Iramp);
% extraction of transition pixels (located on a ramp) with the
% criterion GM>GH and GM>GL
iR = mG(:,M,nZ)>mG(:,H,nZ) & mG(:,M,nZ)>mG(:,L,nZ);
Itrans{iter} = Iramp(iR); % a subset of the ramp pixels
a = zeros(X,Y); a(Itrans{iter}) = 1;
figure, imagesc(a),colormap gray, title('ramp')
%%
% image sharpening
% reshape the input and initialize the output
A = reshape(A,[XY Z]);
SH = A;
% extract ramp pixels of type 1: GL <(or<=) GM <= GH
iR = findcase(p.method, mG(:,H,nZ), mG(:,L,nZ), mG(:,M,nZ));
% note : iR are the coordinates of the pixels considered in the domain
% of the reduced image and Iramp(iR) are the correponding coordinates in
% the domain of the original image
% possibly update those pixels
if ~isempty(iR)
for c=1:Z
F = factorvalue(p.fac, mG(iR,H,c), mG(iR,L,c), mG(iR,M,c));
if strcmp(p.method,'shift')
R = adjustleu(F, mI(iR,L,c), mI(iR,M,c), S(iR), p.fE);
SH(Iramp(iR),c) = updateleu(A(Iramp(iR),c), R, -1);
elseif strcmp(p.method,'control')
R = adjustcontrol(F, mI(iR,L,c), mI(iR,M,c), D(iR,c), ID(iR,c), ...
S(iR), p.fE);
SH(Iramp(iR),c) = updatecontrol(A(Iramp(iR),c),R,mI(iR,L,c));
end
end
end
% extract ramp pixels of type 2: GH <(or<=) GM <= GL
iR = findcase(p.method, mG(:,L,nZ), mG(:,H,nZ), mG(:,M,nZ));
if ~isempty(iR)
for c=1:Z
F = factorvalue(p.fac, mG(iR,L,c), mG(iR,H,c), mG(iR,M,c));
if strcmp(p.method,'shift')
R = adjustleu(F, mI(iR,H,c), mI(iR,M,c), S(iR), p.fE);
SH(Iramp(iR),c) = updateleu(A(Iramp(iR),c), R, 1);
elseif strcmp(p.method,'control')
R = adjustcontrol(F, mI(iR,H,c), mI(iR,M,c), D(iR,c), ID(iR,c), ...
S(iR), p.fE);
SH(Iramp(iR),c) = updatecontrol(A(Iramp(iR),c),R,mI(iR,H,c));
end
end
end
% SH = round(SH);
if p.niter>1
% updates:
% - matrices delta of intensity variation changes
delta = A(Iramp,:) - SH(Iramp,:);
% - matrices dirdelta of change in intensity variation direction
for c=1:Z
dirdeltaI(Iramp(delta(:,c) .* deltaI(Iramp,c) < 0),c) = 1; % sign change
end
deltaI(Iramp,:) = delta;
pchange = sum(abs(delta),2)>eps; % matrix of modified pixels
pchange = sum(pchange(:)) / XY; % pct of change
if p.verb
disp(['iter: ' num2str(iter) ' - ' ...
'modified pix: ' num2str(pchange) ' %']);
end
% note : the first sum: sum(abs(delta),3) operates over the channnel
% account for pixels modified in any of their channel
end
%%
% process for update for next loop in the iteration
A = reshape(SH, [X, Y, Z]);
pl = [pl ; A(110, :)];
pch = [pch ; pchange];
if pchange <= p.pctch
break;
end
% TH: final ramp after the last iteration
iR = findramp(p.method, mG(:,L,nZ), mG(:,H,nZ), mG(:,M,nZ));
TH(Iramp(iR)) = TH(Iramp(iR))+1;
end
% final output
SH = A;
end% end of rampsharp
%% Subfunctions
%%
% |FINDCASE|
%--------------------------------------------------------------------------
function iR = findcase(method, G1, G2, Gm)
iR = G1>=Gm & Gm>G2; % standard Leu condition
if ~strcmp(method,'leu')
iR = iR | (G1>=Gm & Gm==G2); % add flexible condition
end
%iR = find(iR);
end
% end of findcase
%%
% |FINDRAMP|
%--------------------------------------------------------------------------
function iR = findramp(method, G1, G2, Gm)
iR = Gm>=G1 & Gm>=G2; %
if ~strcmp(method,'leu')
iR = iR | (G1>=Gm & Gm==G2); % add flexible condition
end
%iR = find(iR);
end
% end of findramp
%%
% |UPDATECONTROL|
%--------------------------------------------------------------------------
function SH = updatecontrol(A, R, I1)
SH = (A > I1) .* max(A - R, I1) + (A <= I1) .* min(A + R, I1);
end
% end of updatecase
%%
% |UPDATELEU|
%--------------------------------------------------------------------------
function SH = updateleu(A, R, s)
SH = A + s * R;
end
% end of updateleu
%%
% |ADJUSTCONTROL|
%--------------------------------------------------------------------------
function R = adjustcontrol(F, I1, I2, D, ID, S, fE)
R = 0.5 + fE .* F .* S .* abs(I1-I2);
iR0 = D~=0 & ID==1;
% control the current correction amount by the previous correction amount
if ~isempty(iR0)
R(iR0) = max(min(R(iR0), abs(D(iR0))-1), 0);
end
end
% end of adjustcase
%%
% |ADJUSTLEU|
%--------------------------------------------------------------------------
function R = adjustleu(F, I1, I2, S, fE)
R = fE .* S .* abs(I1-I2);
R = (F >= 0.5) .* R + 2. * (F < 0.5) .* F .* R;
end
% end of adjustleu
%%
% |FACTORVALUE|
%--------------------------------------------------------------------------
function F = factorvalue(alpha, G1, G2, Gm)
% compute the correction factor based on the estimated gradient indices
% Gm, Gl (either G1 or G2) and Gh (ibid)
% G1 and G2 stand for Gl or Gh depending on the part of the ramp (lower or
% higher) the pixel belongs to
switch alpha
case {'leu','f0'} % original leu
F = (G1 - Gm) ./ (Gm - G2); % leu-like
case 'f1' % default choice
F = (G2 + Gm) ./ (1 + 2*Gm);
case 'f2'
F = (G1 + G2 - Gm) ./ (1 + 3*Gm);
case 'f3'
F = (G1 + G2) ./ (1 + 2*Gm);
case 'f4'
F = (G1 + Gm) ./ (1 + 2*Gm);
case 'f5'
F = (G1 + G2 + Gm) ./ (1 + 3*Gm);
end
end
% end of factorvalue