import proper
import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
%matplotlib notebook
import cv2 as cv
from skimage import data, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max, canny
from skimage.draw import circle_perimeter, circle
from skimage.util import img_as_ubyte
from scipy import ndimage
from skimage.transform import resize, downscale_local_mean
# old algorithm levels
#threshold1 = 0.16
#threshold2 = 0.205
#threshold1 = 0.18
#threshold2 = 0.24
threshold1 = 0.03
threshold2 = 0.0454
threshold1 = 0.11
threshold2 = 0.118
#threshold1 = 0.3
#threshold2 = 0.3
# ok for unoccluded
#threshold1 = 0.18
#threshold2 = 0.27
# ok for occluded
#threshold1 = 0.27
#threshold2 = 0.38
import random as rng
rng.seed(12345)
def thresh_callback(src_gray, val):
threshold = val
_, contours, _ = cv.findContours(src_gray, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
contours_poly = [None]*len(contours)
centers = [None]*len(contours)
radius = [None]*len(contours)
for i, c in enumerate(contours):
contours_poly[i] = cv.approxPolyDP(c, 3, True)
centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
drawing = np.zeros((src_gray.shape[0], src_gray.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
colore = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours_poly, i, colore)
cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), colore, 2)
print("Max r", np.max(radius))
fig, ax = plt.subplots(1,1, figsize=(15,10))
ax.imshow(drawing + color.gray2rgb(src_gray) )
plt.show()
return np.max(radius)
def plateauLevel(input_image):
imm = np.copy(input_image)
imax = (np.max(input_image))
imm *= 1.0/imax
imm_cap = np.where(imm < threshold1, 0.0, 1.0)
count = np.sum(imm_cap)
guessR = np.sqrt(float(count)/np.pi)
guessCenter = ndimage.measurements.center_of_mass(imm_cap)
plateauRadius = 0.8 * guessR # 0.8 * guessR
print(guessR)
print(guessCenter)
# fig, ax = plt.subplots(1,1, figsize=(15,10))
# ax.imshow(input_image)
# plt.show()
immInnerDisc = input_image*0.0
rr, cc = circle(guessCenter[0], guessCenter[1], plateauRadius)
immInnerDisc[rr, cc] = 1.0
plateauImage = np.where(immInnerDisc >=0.97, input_image, 0.0)
plateauImageMask = np.where(immInnerDisc >=0.97, 1.0, 0.0)
#fig, ax = plt.subplots(1,1, figsize=(15,10))
#ax.imshow(plateauImage)
#plt.show()
plateauLevelOut = np.sum(plateauImage)/np.sum(plateauImageMask)
print('plateauLevel:', plateauLevelOut/imax)
return plateauLevelOut
def computeDiameter(input_image):
imm = np.copy(input_image)
threshold = plateauLevel(imm)
imm *= 1.0/threshold
imm_cap = np.where(imm < threshold2, 0.0, 1.0)
count = np.sum(imm_cap)
guess = 2*int(np.sqrt(float(count)/np.pi))
# print(guess)
#plt.imshow(imm_cap, cmap='hot')
soglie = [0.5]
cx = [0]
cy = [0]
ii = 0
image = (input_image/np.max(input_image))
# imm_cap = resize(imm_cap, (4096, 4096), order=1)
# imm_cap = resize(imm_cap, (2*2472, 2*3296), order=1)
imm_cap = resize(imm_cap, (2*imm_cap.shape[0], 2*imm_cap.shape[1]) , order=1)
sx = ndimage.sobel(imm_cap, axis=0, mode='constant',cval=0)
sy = ndimage.sobel(imm_cap, axis=1, mode='constant',cval=0)
sob = np.hypot(sx, sy)
sob = sob/np.max(sob)
idx = sob[:,:] > soglie[ii]
sob *= 0.0;
sob[idx] = 1
edges = img_as_ubyte(sob)
image_C = color.gray2rgb(edges)
# thresh = 50 # 25 # initial threshold
# rr_alt = thresh_callback(edges, thresh)
# return rr_alt # radius-0.5
hough_radii = np.arange(guess-1, guess+4, 1)
hough_res = hough_circle(edges, hough_radii)
centers = []
accums = []
radii = []
image_C = downscale_local_mean(edges, (4,4))
image_C = color.gray2rgb(image_C)
for radius, h in zip(hough_radii, hough_res):
num_peaks = 1
peaks = peak_local_max(h, num_peaks=num_peaks)
centers.extend(peaks)
accums.extend(h[peaks[:, 0], peaks[:, 1]])
radii.extend([radius] * num_peaks)
# print(radii)
for idx in np.argsort(accums)[::-1][:1]:
center_x, center_y = centers[idx]
center_x = center_x//4
center_y = center_y//4
radius = radii[idx]
ccx, ccy = circle_perimeter(center_y, center_x, radii[idx]//5)
image_C[ccy, ccx] = (255, 0, 0)
center_x, center_y = centers[0]
center_x = center_x//4
center_y = center_y//4
#radius = radii[0]
print('radius', radius)
sss = 900//4
fig, ax = plt.subplots(1,1, figsize=(15,10))
# ax.imshow(image_C[center_x-sss:center_x+sss, center_y-sss:center_y+sss])
ax.imshow(image_C) # [center_x-sss:center_x+sss, center_y-sss:center_y+sss])
plt.show()
cx[ii] = center_x
cy[ii] = center_y
# print('centri', float(center_x)/2.0+0.5, float(center_y)/2.0+0.5)
return radius-0.5
from scipy import stats
def fitAndShow(xx, dd, method=1):
if method==1:
a,b = np.polyfit(dd, xx, 1)
else:
a, b, r_value, p_value, std_err = stats.linregress(dd, xx)
# print('p_value**2:', p_value**2, 'std_err:', std_err)
print('a:', format(a, '.4f'))
# print('1/a:', format(1/a, '.4f'))
print('b:', format(b, '.4f'))
N = float(dd.shape[0])
deltaPrime = N * np.sum(np.multiply(dd,dd)) - np.sum(dd)**2
err = xx - a*dd - b
sigmaSquare = (1.0/(N-2)) * np.sum(np.multiply(xx,xx))
aSigma = (sigmaSquare/deltaPrime) * np.sum(np.multiply(dd,dd))
print( 'aSigma:', format(np.sqrt(aSigma), '.4f') )
print( '(aSigma/a)*100:', format(100*np.sqrt(aSigma)/a, '.3f') )
plt.figure(figsize=(15,10))
plt.plot(dd, xx, 'yo', dd, a*dd+b, '--k')
plt.show()
def showResult_offset(model, r1, s1):
gridsize = r1[0].shape[0]
gridsizeF = float(r1[0].shape[0])
amps = []
phs = []
for i in range(len(r1)):
amp = np.abs(r1[i])
max_amp = np.max(amp)
ph = np.arctan2(np.imag(r1[i]), np.real(r1[i]))
#ph = np.where(amp < 0.01*max_amp, 0.0, ph)
amps.append(amp)
phs.append(ph)
fig, ( (ax11, ax12), (ax13, ax14),(ax21, ax22), (ax23, ax24), (ax31, ax32), (ax33, ax34) ) = plt.subplots(6,2, figsize=(10, 30))
ax11.matshow( amps[0] )
ax12.matshow( phs[0] )
ax21.matshow( amps[1] )
ax22.matshow( phs[1] )
ax31.matshow( amps[2] )
ax32.matshow( phs[2] )
FN = [0] * len(r1)
axplots = [ax13, ax23, ax33]
axplotsP = [ax14, ax24, ax34]
for i in range(len(r1)):
amp = np.abs(r1[i])
max_amp = np.max(amp)
ph = np.arctan2(np.imag(r1[i]), np.real(r1[i]))
ph = np.where(amp < 0.01*max_amp, 0.0, ph)
section = (amp[:, gridsize//2])
sectionP = (ph[:, gridsize//2])
x_coords = np.array(np.linspace( 0, s1[i]*gridsizeF, gridsize)) - s1[i]*gridsizeF/2.0
#axplots[i].set_yticks(np.arange(0, 1., 0.05))
axplots[i].plot(x_coords, section)
#axplotsP[i].set_yticks(np.arange(-2*np.pi, 2*np.pi, 0.3))
axplotsP[i].plot(x_coords, sectionP)
axplots[i].grid()
axplotsP[i].grid()
plt.show()
def showResult_w(model, r1, s1):
gridsize = r1[0].shape[0]
gridsizeF = float(r1[0].shape[0])
fig, (ax4) = plt.subplots(1,1, figsize=(15,10))
FN = [0] * len(r1)
for i in range(len(r1)):
section = (r1[i][:, gridsize//2])
norm_section = (1.0/np.max(section))*section
x_coords = np.array(np.linspace( 0, s1[i]*gridsizeF, gridsize)) - s1[i]*gridsizeF/2.0
section_cap = np.where(norm_section < 0.157, 0.0, 1.0)
ax4.plot(x_coords[gridsize//5:2*gridsize//5], norm_section[gridsize//5:2*gridsize//5])
section_cap_list = section_cap.tolist()
section_cap_diff = np.array([section_cap_list[i] - section_cap_list[i+1] for i in range(len(section_cap_list)-1)])
rx = x_coords[np.where(section_cap_diff>=0.999)]
print(FN)
print(gs1)
plt.show()
from skimage.transform import resize
from skimage import data, img_as_float, exposure
from skimage.draw import circle, rectangle
def lensletArrayScreen( gridsize, sampling, num_lens_per_side, FN, mm ):
wv = 600e-9
k = 2.0*np.pi/wv
print('sampling:', sampling)
si = sampling
print('si:', si)
lens_diam = gridsize // num_lens_per_side
print('lens_diam:', lens_diam)
radiusInPixels = lens_diam // 2
M = radiusInPixels
print('radiusInPixels:', radiusInPixels)
complex_image = np.ones((gridsize, gridsize)).astype(np.complex)
(x1,y1) = np.meshgrid(si*np.arange(-M,M), si*np.arange(-M,M))
r1sq = (x1**2 + y1**2)
focale = FN * mm * lens_diam * si
phi = k*(- r1sq/(2.0*focale) )
print('np.max(phi):', np.max(phi))
print('np.min(phi):', np.min(phi))
# phi1 = np.exp( -1j*2*np.pi*( np.floor(phi/(2*np.pi)) ) )
# phi2 = np.exp( -1j*np.mod(phi, 2*np.pi) )
phi = np.where(r1sq < si*si*M*M, np.exp( 1j*phi), 0.0)
for i in range(int(num_lens_per_side)):
for j in range(int(num_lens_per_side)):
rr, cc = circle(i*lens_diam+radiusInPixels, j*lens_diam+radiusInPixels, radiusInPixels)
complex_image[rr, cc] = 1.0 # + np.exp(-1j*k*si*M/(2.0*FN))
hd = 0 # radiusInPixels # int(lens_diam//2)
dd = lens_diam+hd - phi.shape[0]
complex_image[i*lens_diam+hd:(i+1)*lens_diam+hd-dd, j*lens_diam+hd:(j+1)*lens_diam+hd-dd] = phi
return complex_image
def lensletArrayScreenPhase( gridsize, sampling, num_lens_per_side, FN ):
wv = 600e-9
k = 2.0*np.pi/wv
print('sampling:', sampling)
si = sampling # / float(gridsize)
print('si:', si)
lens_diam = gridsize // num_lens_per_side
print('lens_diam:', lens_diam)
radiusInPixels = lens_diam // 2
M = radiusInPixels
print('radiusInPixels:', radiusInPixels)
complex_image = np.ones((gridsize, gridsize)).astype(np.float)
(x1,y1) = np.meshgrid(si*np.arange(-M,M), si*np.arange(-M,M))
r1sq = (x1**2 + y1**2)
focale = FN * lens_diam * si
phi = -k*r1sq/(2.0*focale)
# phi = np.exp(1j*phi)
for i in range(int(num_lens_per_side)):
for j in range(int(num_lens_per_side)):
rr, cc = circle(i*lens_diam+radiusInPixels, j*lens_diam+radiusInPixels, radiusInPixels)
complex_image[rr, cc] = 1.0 # + np.exp(-1j*k*si*M/(2.0*FN))
hd = 0 # radiusInPixels # int(lens_diam//2)
dd = 0
complex_image[i*lens_diam+hd:(i+1)*lens_diam+hd-dd, j*lens_diam+hd:(j+1)*lens_diam+hd-dd] = phi
return complex_image
def complexDisplay(image):
f, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize = (5, 15))
imageAmp = np.abs(image)
ax1.imshow(imageAmp, cmap = 'hot')
ax2.imshow(np.arctan2(image.imag, image.real), cmap = 'hot')
N = image.shape[0]
xx = 1.0* np.arange(-N/2,N/2)
ax3.plot(xx, imageAmp[N//2,:])
plt.show()
def simple_telescope(wavelength, gridsize, d_objective, offset, phaseOn=True, period = 2.0, dist_amp = 1.0, lenslet=False):
d_collimator = (5.0/17.7) * (d_objective/40.0)
fl_objective = 17.7 * d_objective # objective focal length in meters
fl_collimator = 17.7 * d_collimator # eyepiece focal length
beam_ratio = 1.0 # 0.75 # initial beam width/grid width
wfos = []
samplings = []
ff = 1.3
wfo = proper.prop_begin((d_objective)*ff, wavelength, gridsize, beam_ratio)
proper.prop_circular_aperture(wfo, (d_objective/2.0)*ff)
proper.prop_define_entrance(wfo)
if phaseOn:
m = 2.0 * np.pi * dist_amp
x = (np.arange(gridsize, dtype = np.float64) - gridsize/2) * proper.prop_get_sampling(wfo)
grating = m * (np.cos((2*np.pi/period)*x)+1) * 0.5
# create 2-D amplitude grating pattern
grating = np.dot(grating.reshape(gridsize,1), np.ones([1,gridsize], dtype = np.float64))
grating_pahse = np.exp(1j*grating)
proper.prop_multiply(wfo, grating_pahse)
#wfos.append(proper.prop_get_wavefront(wfo))
#samplings.append(proper.prop_get_sampling(wfo))
proper.prop_propagate(wfo, 10e3, "from atmosphere layer", TO_PLANE=False)
wfos.append(proper.prop_get_wavefront(wfo))
samplings.append(proper.prop_get_sampling(wfo))
proper.prop_circular_aperture(wfo, d_objective/2)
proper.prop_lens(wfo, fl_objective, "objective")
proper.prop_propagate(wfo, fl_objective+fl_collimator, "collimator", TO_PLANE=False)
wfos.append(proper.prop_get_wavefront(wfo))
samplings.append(proper.prop_get_sampling(wfo))
proper.prop_circular_aperture(wfo, d_collimator/2)
proper.prop_lens(wfo, fl_collimator, "collimator")
#exit_pupil_distance = fl_collimator / (1.0 - fl_collimator/(fl_objective+fl_collimator))
exit_pupil_distance = fl_collimator - 10e3* (fl_collimator/fl_objective) ** 2
print(exit_pupil_distance) # layer distance
print('exit_pupil_distance:', exit_pupil_distance-offset)
proper.prop_propagate(wfo, exit_pupil_distance-offset, "exit pupil", TO_PLANE=True)
if lenslet:
n_lens = 10
FN_lenslet_array = 3.0 # 40.0
FN_one_lenslet = FN_lenslet_array * n_lens
#lenslet_screen_phase = lensletArrayScreenPhase(gridsize, proper.prop_get_sampling(wfo), n_lens*2, FN_lenslet)
#proper.prop_add_phase(wfo, lenslet_screen_phase)
mm = 1
lenslet_screen = lensletArrayScreen(gridsize, proper.prop_get_sampling(wfo), n_lens*1.3 + 1, FN_one_lenslet, mm)
complexDisplay(lenslet_screen)
proper.prop_multiply(wfo, lenslet_screen)
proper.prop_propagate(wfo, mm * FN_lenslet_array * d_collimator, "exit pupil", TO_PLANE=True)
wfos.append(proper.prop_get_wavefront(wfo))
samplings.append(proper.prop_get_sampling(wfo))
(wfo, sampling) = proper.prop_end(wfo, NOABS = True)
return (wfos, samplings)
def runmodel_mono(model, system=simple_telescope):
gridsize = model['grid_size']
wavelengths = model['wavelengths']
beam_ratio = model['beam_ratio']
pahse_on = model['pahse_on']
r1, s1 = system(wavelengths[0], gridsize, model['aperture_diameter'], model['offset'][0], pahse_on, model['dist_period'], model['dist_amp'], model['lenslet'])
return r1, s1
model0a = {}
model0a['grid_size'] = 1024*16
model0a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model0a['beam_ratio'] = 0.5
model0a['offset'] = np.linspace(0, 0, 1)
model0a['aperture_diameter'] = 40.0
model0a['pahse_on'] = True
model0a['dist_period'] = 1.0
model0a['dist_amp'] = 0.05
model0a['lenslet'] = True
#rrt1, r1 = runmodel_w(model1)
r0a, s0a = runmodel_mono(model0a)
print(s0a)
showResult_offset(model0a, r0a, s0a)
model0a = {}
model0a['grid_size'] = 1024*8
model0a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model0a['beam_ratio'] = 0.5
model0a['offset'] = np.linspace(0, 0, 1)
model0a['aperture_diameter'] = 40.0
model0a['pahse_on'] = True
model0a['dist_period'] = 1.0
model0a['dist_amp'] = 0.05
model0a['lenslet'] = True
#rrt1, r1 = runmodel_w(model1)
r0a, s0a = runmodel_mono(model0a)
print(s0a)
showResult_offset(model0a, r0a, s0a)
model0a = {}
model0a['grid_size'] = 1024*2
model0a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model0a['beam_ratio'] = 0.5
model0a['offset'] = np.linspace(0, 0, 1)
model0a['aperture_diameter'] = 40.0
model0a['pahse_on'] = True
model0a['dist_period'] = 1.0
model0a['dist_amp'] = 0.05
model0a['lenslet'] = True
#rrt1, r1 = runmodel_w(model1)
r0a, s0a = runmodel_mono(model0a)
print(s0a)
showResult_offset(model0a, r0a, s0a)
model3a = {}
model3a['grid_size'] = 1024*4
model3a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model3a['beam_ratio'] = 0.5
model3a['offset'] = np.linspace(2.5, 2.5, 1)
model3a['aperture_diameter'] = 40.0
model3a['pahse_on'] = True
model3a['dist_period'] = 1.0
model3a['dist_amp'] = 1.0
model3a['lenslet'] = False
r3a, s3a = runmodel_mono(model3a)
print(s3a)
showResult_offset(model3a, r3a, s3a)
model2a = {}
model2a['grid_size'] = 1024*4
model2a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model2a['beam_ratio'] = 0.5
model2a['offset'] = np.linspace(0, 0, 1)
model2a['aperture_diameter'] = 40.0
model2a['pahse_on'] = True
model2a['dist_period'] = 1.0
model2a['dist_amp'] = 1.0
model2a['lenslet'] = False
#rrt1, r1 = runmodel_w(model1)
r2a, s2a = runmodel_mono(model2a)
print(s2a)
showResult_offset(model2a, r2a, s2a)
model1a = {}
model1a['grid_size'] = 1024*4
model1a['wavelengths'] = np.linspace(600*1e-9, 600*1e-9, 1)
model1a['beam_ratio'] = 0.5
model1a['offset'] = np.linspace(0, 0, 1)
model1a['aperture_diameter'] = 40.0
model1a['pahse_on'] = True
model1a['dist_period'] = 1.0
model1a['dist_amp'] = 0.2
model1a['lenslet'] = False
#rrt1, r1 = runmodel_w(model1)
r1a, s1a = runmodel_mono(model1a)
print(s1a)
showResult_offset(model1a, r1a, s1a)