Skip to content

Commit db5edb8

Browse files
committed
added getDcorr1D.m function prototype for frequency support estimation of 1D signal
1 parent f009408 commit db5edb8

File tree

2 files changed

+206
-2
lines changed

2 files changed

+206
-2
lines changed

funcs/getDcorr1D.m

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
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

funcs/getDcorrLocalMax.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
function [ind,A] = getDcorrLocalMax(d)
3838

3939
Nr = numel(d);
40-
if Nr < 3
40+
if Nr < 2
4141
ind = 1;
4242
A = d(1);
4343
else
@@ -49,7 +49,7 @@
4949
[A,ind] = max(d);
5050
elseif ind == 1
5151
break;
52-
elseif (A - min(d(ind:end))) > 0.01
52+
elseif (A - min(d(ind:end))) >= 0.001
5353
break;
5454
else
5555
d(end) = [];

0 commit comments

Comments
 (0)