Skip to content

Commit 504b707

Browse files
Yaml refactor (#31)
* Updated configuration and experiment yaml files All the calls to it are now broken. Working on that next. * Fixed paths in yaml refactor I suspect there are more path breaks lurking, but using the --synthetic_hardware call it is now bringing up the GUI. Available for evaluation @codeCollision4 and @annie-xd-wang. Hopefully the experiment file that I put up is also clear. I am available for a discussion if you would like probably around 12:30 PM my time. * Added documentation for the remote focusing devices
1 parent ff0b21a commit 504b707

10 files changed

+596
-174
lines changed

src/analysis/flatfield.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,13 @@ def baseline_drift(images_list,
204204
ent1 = 1
205205
_iter = 0
206206
total_svd = 0
207-
converged = False;
207+
converged = False
208208
A1_hat = np.zeros(resized_images.shape)
209209
E1_hat = np.zeros(resized_images.shape)
210210
Y1 = 0
211211

212212
while not converged:
213-
_iter = _iter + 1;
213+
_iter = _iter + 1
214214
A1_hat = W_idct_hat * A1_coeff + A_offset
215215

216216
# update E1 using l0 norm

src/analysis/image_decorrelation.py

+378
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
import numpy as np
2+
import numpy.matlib
3+
from tifffile import imread, imsave
4+
import matplotlib.pyplot as plt
5+
import matplotlib.image as mpimg
6+
import pretty_errors
7+
8+
def getDcorrMax(d):
9+
'''
10+
# ---------------------------------------
11+
#
12+
# Return the local maxima of the decorrelation function d
13+
#
14+
# Inputs:
15+
# d Decorrelation function
16+
#
17+
# Outputs:
18+
# ind Position of the local maxima
19+
# A Amplitude of the local maxima
20+
#
21+
# ---------------------------------------
22+
'''
23+
24+
ind = np.argmax(d)
25+
A = d[ind]
26+
t = d;
27+
# arbitrary peak significance parameter imposed by numerical noise
28+
# this becomes relevant especially when working with post-processed data
29+
dt = 0.001;
30+
31+
while ind == np.shape(t)[0]:
32+
t[-1] = []
33+
if np.isempty(t):
34+
A = 0
35+
ind = 1
36+
else:
37+
ind = np.argmax(t)
38+
A = t[ind]
39+
# check if the peak is significantly larger than the former minimum
40+
if t[ind] - np.min(d[ind:-1]) > dt:
41+
break
42+
else:
43+
t[ind] = np.min(d[ind:-1])
44+
ind = np.shape(t)[0]
45+
46+
return ind, A
47+
48+
def getDcorrLocalMax(d):
49+
'''
50+
# [ind,A] = getDcorrLocalMax(d)
51+
# ---------------------------------------
52+
#
53+
# Return the local maxima of the decorrelation function d
54+
#
55+
# Inputs:
56+
# d Decorrelation function
57+
#
58+
# Outputs:
59+
# ind Position of the local maxima
60+
# A Amplitude of the local maxima
61+
#
62+
# ---------------------------------------
63+
'''
64+
numel = np.shape(d)
65+
numel = numel[0]
66+
67+
if numel < 1:
68+
ind = 0
69+
A = d[0]
70+
else:
71+
ind = np.argmax(d)
72+
A = d[ind]
73+
while numel > 1:
74+
# if the last indexed position
75+
if ind == numel:
76+
d[-1] = []
77+
ind = np.argmax(d)
78+
A = d[ind]
79+
80+
# If the first indexed position
81+
elif ind == 0:
82+
break
83+
84+
# If the minimum amplitude between ind and the last index is above a threshold
85+
elif (A - np.min(d[ind:-1])) >= 0.0005:
86+
break
87+
88+
# If the threshold is not met.
89+
else:
90+
d[-1] = []
91+
ind = np.argmax(d)
92+
A = d[ind]
93+
94+
if ind.size == 0:
95+
ind = 0
96+
A = d[0]
97+
98+
else:
99+
A = d[ind]
100+
101+
return ind, A
102+
103+
def linear_map(val, valMin, valMax):
104+
'''
105+
# rsc = linear_map(val,valMin,valMax,mapMin,mapMax)
106+
# ---------------------------------------
107+
#
108+
# Performs a linear mapping of val from the range [valMin,valMax] to the range [mapMin,mapMax]
109+
#
110+
# Inputs:
111+
# val Input value
112+
# valMin Minimum value of the range of val
113+
# valMax Maximum value of the range of val
114+
# mapMin Minimum value of the new range of val
115+
# mapMax Maximum value of the new range of val
116+
#
117+
# Outputs:
118+
# rsc Rescaled value
119+
#
120+
# Example : rsc = linear_map(val,0,255,0,1); # map the uint8 val to the range [0,1]
121+
#
122+
# ---------------------------------------
123+
'''
124+
125+
mapMin = valMin
126+
mapMax = valMax
127+
valMin = np.min(val)
128+
valMax = np.max(val)
129+
130+
# convert the input value between 0 and 1
131+
tempVal = (val-valMin)/(valMax-valMin)
132+
133+
# clamp the value between 0 and 1
134+
map0 = tempVal < 0
135+
map1 = tempVal > 1
136+
tempVal[map0] = 0
137+
tempVal[map1] = 1
138+
139+
# rescale and return
140+
rsc = np.multiply(tempVal, (mapMax-mapMin)) + mapMin
141+
return rsc
142+
143+
def apod_im_rect(image, N):
144+
'''
145+
# [out,mask] = apodImRect(in,N)
146+
# ---------------------------------------
147+
#
148+
# Apodize the edges of a 2D image
149+
#
150+
# Inputs:
151+
# in Input image
152+
# N Number of pixels of the apodization
153+
#
154+
# Outputs:
155+
# out Apodized image
156+
# mask Mask used to apodize the image
157+
#
158+
# ---------------------------------------
159+
'''
160+
161+
number_x, number_y = np.shape(image)
162+
163+
x = np.abs(np.linspace(-number_x/2, number_x/2, number_x))
164+
y = np.abs(np.linspace(-number_y/2, number_y/2, number_y))
165+
mapx = x > (number_x/2 - N)
166+
mapy = y > (number_y/2 - N)
167+
168+
val = np.mean(image)
169+
170+
d = np.multiply((-np.abs(x) - np.mean(-np.abs(x[mapx]))), mapx)
171+
d = linear_map(d, -np.pi/2, np.pi/2)
172+
d[mapx == False] = np.pi/2
173+
maskx = (np.sin(d)+1)/2
174+
175+
d = np.multiply((-np.abs(y) - np.mean(-np.abs(y[mapy]))), mapy)
176+
d = linear_map(d, -np.pi/2, np.pi/2)
177+
d[mapy == False] = np.pi/2
178+
masky = (np.sin(d)+1)/2
179+
180+
# Make it 2D
181+
# np.matlib.repmat(a, m, n). a: array/matrix. m,n: int - number of times a is repeated on first and second axes.
182+
mask_1 = np.matlib.repmat(masky, number_x, 1)
183+
mask_2 = np.matlib.repmat(maskx, number_y, 1)
184+
mask_2 = np.transpose(mask_2)
185+
mask = np.multiply(mask_1, mask_2)
186+
187+
out = np.multiply((image-val), mask) + val
188+
189+
return out
190+
191+
def getCorrcoef(I1, I2, c1=None, c2=None):
192+
'''
193+
# cc = getCorrcoef(I1,I2,c1,c2)
194+
# ---------------------------------------
195+
#
196+
# Return the normalized correlation coefficient expressed in Fourier space
197+
#
198+
# Inputs:
199+
# I1 Complex Fourier transfom of image 1
200+
# I2 Complex Fourier transfom of image 2
201+
#
202+
# Outputs:
203+
# cc Normalized cross-correlation coefficient
204+
'''
205+
206+
if c1 == None:
207+
c1 = np.square(np.sqrt(np.sum(np.sum(np.abs(I1)))))
208+
209+
if c2 == None:
210+
c2 = np.square(np.sqrt(np.sum(np.sum(np.abs(I2)))))
211+
import warnings
212+
warnings.simplefilter("ignore", np.ComplexWarning)
213+
a = np.sum(np.real(np.multiply(I1, np.conjugate(I2))))
214+
b = c1*c2
215+
np.seterr(invalid='ignore')
216+
cc = np.divide(a, b)
217+
cc = np.double(cc)
218+
cc = np.floor(1000*cc)/1000
219+
return cc
220+
221+
def getDCorr(im, r=None, Ng=10, figID=0):
222+
verbose = True
223+
if r is None:
224+
r = np.linspace(0, 1, 50)
225+
226+
if np.shape(r)[0] < 30:
227+
r = np.linspace(np.min(r), np.max(r), 30)
228+
229+
if Ng < 5:
230+
Ng = 5
231+
232+
im = np.single(im)
233+
234+
# Make size odd numbers only.
235+
number_x, number_y = np.shape(im)
236+
if np.mod(number_x, 2) == 0:
237+
im = np.delete(im, 0, 0)
238+
if np.mod(number_y, 2) == 0:
239+
im = np.delete(im, 0, 1)
240+
241+
number_x, number_y = np.shape(im)
242+
243+
x = np.linspace(-1, 1, number_x)
244+
y = np.linspace(-1, 1, number_y)
245+
x, y = np.meshgrid(x, y)
246+
R = np.sqrt(x**2 + y**2)
247+
Nr = np.shape(r)[0]
248+
249+
# In = Fourier Normalized Image
250+
In = np.fft.fftshift(np.fft.fft2(np.fft.fftshift(im)))
251+
In = np.divide(In, np.abs(In))
252+
In[np.isinf(In)] = 0
253+
In[np.isnan(In)] = 0
254+
mask0 = R**2 < 1**2
255+
In = np.multiply(np.transpose(mask0), In)
256+
257+
# Ik = Fourier Transform of Image
258+
Ik = np.multiply(np.transpose(mask0), np.fft.fftshift(np.fft.fft2(np.fft.fftshift(im))))
259+
c = np.sqrt(np.sum(np.multiply(Ik, np.conjugate(Ik))))
260+
r0 = np.linspace(r[0], r[-1], Nr)
261+
262+
d0 = np.zeros(np.shape(r)[0])
263+
for k in range(np.shape(r)[0], 0, -1):
264+
cc = getCorrcoef(Ik, np.transpose(np.square(R)) < np.multiply(r0[k-1]**2, In), c)
265+
if np.isnan(cc):
266+
cc = 0
267+
d0[k-1] = cc
268+
269+
ind0, snr0 = getDcorrLocalMax(d0)
270+
271+
k0 = r[ind0]
272+
gMax = 2/r0[ind0]
273+
274+
if np.isinf(gMax):
275+
gMax = max(np.shape(im)[0], np.shape(im)[1])/2
276+
277+
# Search for the Highest Frequency Peak
278+
g = np.hstack((np.shape(im)[0]/4, np.exp(np.linspace(np.log(gMax), np.log(0.15), Ng))))
279+
d = np.zeros((Nr, 2*Ng))
280+
281+
number_iterations = 2
282+
kc = np.zeros(np.shape(g)[0]*number_iterations)
283+
kc[0] = k0
284+
285+
SNR = np.zeros(np.shape(g)[0]*number_iterations)
286+
SNR[0] = snr0
287+
288+
ind0 = 0
289+
290+
291+
# Two Step Refinement
292+
for refin in range(number_iterations): # 0, 1.
293+
for h in range(np.shape(g)[0]): # 0..10
294+
295+
# Fourier Gaussian Filtering
296+
Ir = np.multiply(np.transpose(Ik), (1 - np.exp(-2*g[h]*g[h]*R**2)))
297+
c = np.sqrt(np.sum(np.abs(Ir)**2))
298+
299+
for k in range(np.shape(r)[0]-1, ind0-1, -1): # 49...0
300+
mask = R**2 < r[k]**2
301+
cc = getCorrcoef(Ir[mask], In[np.transpose(mask)], c)
302+
if np.isnan(cc):
303+
cc = 0
304+
d[k, h + (Ng * refin) - 1] = cc
305+
306+
ind, amp = getDcorrLocalMax(d[k:-1, h + (Ng * refin) - 1])
307+
308+
snr = d[ind, h + (Ng * refin) - 1]
309+
ind = ind + k
310+
311+
kc[h + Ng * refin + 1] = r[ind]
312+
SNR[h + Ng * refin + 1] = snr
313+
314+
print("kc :", kc)
315+
print("SNR :", SNR)
316+
317+
318+
return 5, 5
319+
320+
def main_image_decorr():
321+
'''
322+
https://github.com/Ades91/ImDecorr/blob/master/main_imageDecorr.m
323+
'''
324+
# Load the Data
325+
raw_image = np.array(imread('/Users/S155475/Local/Publication materials/2020-SOLS/Data/MV3Membrane/LateralInsets/DetailVesicleTimepoint30.tif'))
326+
raw_image = np.double(raw_image)
327+
328+
# projected pixel size
329+
pps = 5
330+
331+
Nr = 50
332+
Ng = 10
333+
r = np.linspace(0, 1, Nr)
334+
335+
GPU = False
336+
337+
# Apodize Image Edges with a Cosine Function over 20 pixels
338+
image = apod_im_rect(raw_image, 20)
339+
340+
# Compute Resolution
341+
figID = 100
342+
if GPU:
343+
pass # [kcMax,A0] = getDcorr(gpuArray(image),r,Ng,figID); gpuDevice(1);
344+
else:
345+
kcMax, A0 = getDCorr(image, r, Ng, figID)
346+
347+
print("kcMax :", kcMax, "A0 :", A0)
348+
349+
# sectorial resolution
350+
Na = 8 # number of sectors
351+
figID = 101
352+
if GPU:
353+
pass # [kcMax,A0] = getDcorrSect(gpuArray(image),r,Ng,Na,figID); gpuDevice(1);
354+
else:
355+
pass #kcMax, A0 = getDcorrSect(image,r,Ng,Na,figID)
356+
357+
# Local resolution map
358+
tileSize = 200 # in pixels
359+
tileOverlap = 0 # in pixels
360+
figId = 103
361+
362+
if GPU:
363+
pass # [kcMap,A0Map] = getLocalDcorr(gpuArray(image),tileSize,tileOverlap,r,Ng,figID);gpuDevice(1);
364+
else:
365+
pass # kcMap, A0Map = getLocalDcorr(image,tileSize,tileOverlap,r,Ng,figID)
366+
367+
return kcMax, A0
368+
369+
370+
if (__name__ == '__main__'):
371+
kcMax, AO = main_image_decorr()
372+
373+
374+
375+
376+
377+
378+
print("Guess we are done here")

0 commit comments

Comments
 (0)