1+ function [kcMax ,A0 ,d0 ,d ] = getDcorr1D(sig ,r ,Ng ,figID )
2+
3+ if nargin < 4 ; figID = 0 ; end
4+ if ischar(figID )
5+ figID = 0 ;
6+ fastMode = 1 ;
7+ else
8+ fastMode = 0 ;
9+ end
10+ if nargin < 3 ; Ng = 10 ; end
11+ if nargin < 2 ; r = linspace(0 ,1 ,50 ); end
12+
13+ % input check
14+ if length(r ) < 30
15+ r = linspace(min(r ),max(r ),min(30 ,(numel(sig )+1 )/2 ));
16+ elseif length(r ) > (numel(sig )+1 )/2
17+ r = linspace(min(r ),max(r ),(numel(sig )+1 )/2 );
18+ end
19+ if Ng < 5
20+ Ng = 5 ;
21+ end
22+ if size(sig ,1 ) > 1 && size(sig ,2 ) == 1
23+ sig = sig ' ;
24+ end
25+ sig = single(sig );
26+ sig = sig(1 : end - not(mod(numel(sig ),2 ))); % odd number of pixels
27+
28+ R = abs(linspace(-1 ,1 ,numel(sig )));
29+ Nr = length(r );
30+ if isa(sig ,' gpuArray' )
31+ r = gpuArray(r );
32+ R = gpuArray(R );
33+ end
34+ % Sn : Fourier normalized signal
35+ Sn = fftshift(fft(fftshift(sig ))); Sn = Sn ./ abs(Sn ); Sn(isinf(Sn )) = 0 ; Sn(isnan(Sn )) = 0 ;
36+ mask0 = R <= 1 ;
37+ Sn = mask0 .* Sn ; % restric all the analysis to the region r < 1
38+
39+ if figID
40+ fprintf(' Computing dcorr: ' );
41+ end
42+
43+ Sk = mask0 .* fftshift(fft(fftshift(sig )));
44+
45+ c = sqrt(sum(sum(Sk .* conj(Sk ))));
46+
47+ r0 = linspace(r(1 ),r(end ),Nr );
48+
49+ for k = length(r0 ): -1 : 1
50+ cc = getCorrcoef(Sk ,(R < r0(k )).*Sn ,c );
51+ if isnan(cc ); cc = 0 ; end
52+ d0(k ) = gather(cc ); % gather if input image is gpuArray
53+
54+ if fastMode == 1
55+ [ind0 ,snr0 ] = getDcorrLocalMax(d0(k : end ));
56+ ind0 = ind0 + k - 1 ;
57+ if ind0 > k % found a local maxima, skip the calculation
58+ break ;
59+ end
60+ end
61+ end
62+ if fastMode == 0
63+ % d0(k:end) = d0(k:end).*sqrt(r0(k:end));
64+ ind0 = getDcorrLocalMax(d0(k : end ));
65+ snr0 = d0(ind0 );
66+ end
67+ k0 = gather(r(ind0 ));
68+
69+ gMax = 2 / r0(ind0 );
70+ if isinf(gMax ); gMax = max(numel(sig ))/2 ;end
71+
72+ % search of highest frequency peak
73+ g = [numel(sig / 4 )/4 , exp(linspace(log(gMax ),log(0.15 ),Ng ))];
74+ d = zeros(Nr ,2 * Ng ); kc = k0 ; SNR = snr0 ;
75+ if fastMode == 0
76+ ind0 = 1 ;
77+ else
78+ if ind0 > 1
79+ ind0 = ind0 - 1 ;
80+ end
81+ end
82+ for refin = 1 : 2 % two step refinement
83+
84+ for h = 1 : length(g )
85+ Sr = Sk .*(1 - exp(-2 * g(h )*g(h )*R .^ 2 )); % Fourier Gaussian filtering
86+
87+ c = sqrt(sum(sum(abs(Sr ).^2 )));
88+
89+ for k = length(r ): -1 : ind0
90+
91+ if isa(sig ,' gpuArray' )
92+ cc = getCorrcoef(Sr ,Sn .*(R < r(k )),c );
93+ if isnan(cc ); cc = 0 ; end
94+ d(k ,h + Ng *(refin - 1 )) = gather(cc );
95+ else
96+ mask = (R < r(k ));
97+ cc = getCorrcoef(Sr(mask ),Sn(mask ),c );
98+ if isnan(cc ); cc = 0 ; end
99+ d(k ,h + Ng *(refin - 1 )) = cc ;
100+ end
101+ if fastMode
102+ [ind ,snr ] = getDcorrLocalMax(d(k : end ,h + Ng *(refin - 1 )));
103+ ind = ind + k - 1 ;
104+ if ind > k % found a local maxima, skip the calculation
105+ break ;
106+ end
107+ end
108+
109+ end
110+ if fastMode == 0
111+ % d(k:end,h + Ng*(refin-1)) = d(k:end,h + Ng*(refin-1)).*sqrt(r(k:end)');
112+ ind = getDcorrLocalMax(d(k : end ,h + Ng *(refin - 1 )));
113+ snr = d(ind ,h + Ng *(refin - 1 ));
114+ ind = ind + k - 1 ;
115+ end
116+ kc(h + Ng *(refin - 1 )+1 ) = gather(r(ind ));
117+ SNR(h + Ng *(refin - 1 )+1 ) = snr ;
118+ if figID
119+ fprintf(' -' );
120+ end
121+ end
122+
123+ % refining the high-pass threshold and the radius sampling
124+ if refin == 1
125+
126+ % high-pass filtering refinement
127+ indmax = find(kc == max(kc ));
128+ ind1 = indmax(end );
129+ if ind1 == 1 % peak only without highpass
130+ ind1 = 1 ;
131+ ind2 = 2 ;
132+ g1 = size(sig ,1 );
133+ g2 = g(1 );
134+ elseif ind1 >= numel(g )
135+ ind2 = ind1 - 1 ;
136+ ind1 = ind1 - 2 ;
137+ g1 = g(ind1 ); g2 = g(ind2 );
138+ else
139+ ind2 = ind1 ;
140+ ind1 = ind1 - 1 ;
141+ g1 = g(ind1 ); g2 = g(ind2 );
142+ end
143+ g = exp(linspace(log(g1 ),log(g2 ),Ng ));
144+
145+ % radius sampling refinement
146+
147+ r1 = kc(indmax(end ))-(r(2 )-r(1 )); r2 = kc(indmax(end ))+0.3 ;
148+ if r1 < 0 ; r1 = 0 ; end
149+ if r2 > 1 ; r2 = 1 ; end
150+ r = linspace(r1 ,min(r2 ,r(end )),Nr );
151+ ind0 = 1 ;
152+ r2 = r ;
153+ end
154+ end
155+ if figID
156+ fprintf(' -- Computation done -- \n ' );
157+ end
158+
159+ % add d0 results to the analysis (usefull for high noise images)
160+ kc(end + 1 ) = gather(k0 );
161+ SNR(end + 1 ) = snr0 ;
162+
163+ % % need at least 0.05 of SNR to be even considered
164+ kc(SNR < 0.05 ) = 0 ;
165+ SNR(SNR < 0.05 ) = 0 ;
166+
167+ snr = SNR ;
168+
169+ % output results computation
170+ if ~isempty(kc )
171+ % highest resolution found
172+ [kcMax ,ind ] = max(kc );
173+ AMax = SNR(ind );
174+ A0 = snr0 ; % average image contrast has to be estimated from original image
175+ else
176+ kcMax = r(2 );
177+ Amax = 0 ;
178+ res = r(2 );
179+ A0 = 0 ;
180+ end
181+
182+ % results display if figID specified
183+ if figID
184+ radAv = log(abs(gather(Sk((end + 1 )/2 : end )))+1 );
185+ lnwd = 1.5 ;
186+ figure(figID );
187+ plot(r0 ,d(: ,1 : Ng ),' color' ,[0.2 0.2 0.2 0.5 ]);
188+ hold on
189+
190+ plot(linspace(0 ,1 ,length(radAv )),linmap(radAv ,0 ,1 ),' linewidth' ,lnwd ,' color' ,[1 0 1 ])
191+ for n = 1 : Ng
192+ plot(r2 ,d(: ,n + Ng ),' color' ,[0 0 (n - 1 )/Ng ])
193+ end
194+ plot(r0 ,d0 ,' linewidth' ,lnwd ,' color' ,' g' )
195+ plot([kcMax kcMax ],[0 1 ],' k' )
196+ for k = 1 : length(kc )
197+ plot(kc(k ),snr(k ),' bx' ,' linewidth' ,1 )
198+ end
199+ hold off
200+ title([' Dcor analysis : res ~ ' ,num2str(kcMax ,4 ),' , SNR ~ ' ,num2str(A0 ,4 )])
201+ xlim([0 1 ]); ylim([0 1 ])
202+ xlabel(' Normalized spatial frequencies' )
203+ ylabel(' C.c. coefficients' )
204+ end
0 commit comments