Spaces:
Sleeping
Sleeping
Add download button
Browse files- app.py +46 -12
- fraunhofer_test.py +107 -10
- generate_dataset.py +48 -66
- zern_generator.py +12 -6
app.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import matplotlib.pyplot as plt
|
| 3 |
#from fraunhofer_test import generate_diff
|
| 4 |
from zern_generator import Zernike
|
| 5 |
from fraunhofer_test import Fraunhofer
|
|
|
|
|
|
|
|
|
|
| 6 |
css = """
|
| 7 |
.container {
|
| 8 |
# height: 50vh;
|
|
@@ -29,19 +34,25 @@ def get_zern_from_file(file):
|
|
| 29 |
|
| 30 |
zernike = Zernike()
|
| 31 |
fraunhofer = Fraunhofer(zernike)
|
| 32 |
-
|
| 33 |
theme = gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)
|
| 34 |
with gr.Blocks(theme=theme, css=css) as demo:
|
| 35 |
with gr.Row():
|
| 36 |
zern_sliders = []
|
| 37 |
-
|
| 38 |
with gr.Column(scale=1):
|
| 39 |
-
# file_inp = gr.File(label="Загрузка коэффициентов из файла", height="2em")
|
| 40 |
with gr.Tab(label="Генератор"):
|
| 41 |
|
| 42 |
-
defocus_amt = gr.Number(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
with gr.Row():
|
| 44 |
-
num_zernikes = gr.Number(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
show_zernikes_btn = gr.Button("Показать")
|
| 46 |
sliders_container = gr.Column(elem_classes=["container"])
|
| 47 |
|
|
@@ -53,8 +64,14 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
| 53 |
count = min(count, 100)
|
| 54 |
for i in range(count):
|
| 55 |
term_name = f" - {zernike.term[i]}" if i < len(zernike.term) else ""
|
| 56 |
-
sld = gr.Slider(
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
sld.change(update_zerns, inputs=[gr.Number(value=i, visible=False), sld])
|
| 60 |
sliders_container.add_child(sld)
|
|
@@ -64,7 +81,6 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
| 64 |
with gr.Tab(label="Настройки"):
|
| 65 |
resolution_num = gr.Number(value=256, label="Разрешение")
|
| 66 |
|
| 67 |
-
# file_inp.upload(get_zern_from_file, inputs=[file_inp], outputs=[*sliders_container.children])
|
| 68 |
|
| 69 |
with gr.Column(scale=5):
|
| 70 |
with gr.Tab(label="Экран"):
|
|
@@ -77,7 +93,9 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
| 77 |
btn_batch = gr.Button("Рассчитать тестовые экраны")
|
| 78 |
with gr.Tab(label="Разница у фокуса"):
|
| 79 |
plot_diff = gr.Plot(label="Разница в фокусе")
|
|
|
|
| 80 |
btn_diff = gr.Button("Рассчитать разницу в фокусе")
|
|
|
|
| 81 |
|
| 82 |
def on_button_click(resolution):
|
| 83 |
return zernike.generate_zern_wavefront_fig(*[zerns[key] for key in sorted(zerns)])
|
|
@@ -85,10 +103,16 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
| 85 |
def on_settings_click(resolution):
|
| 86 |
print(resolution)
|
| 87 |
zernike.set_image_params(npix=resolution)
|
| 88 |
-
|
|
|
|
|
|
|
|
|
|
| 89 |
def on_diff_button_click(defocus_amount):
|
|
|
|
|
|
|
|
|
|
| 90 |
pl, mn, diff = fraunhofer.generate_diff(defocus_amount, *[zerns[key] for key in sorted(zerns)])
|
| 91 |
-
|
| 92 |
fig, axs = plt.subplots(1, 3, figsize = (20, 10))
|
| 93 |
axs[0].imshow(pl, cmap='grey')
|
| 94 |
axs[1].imshow(mn, cmap='grey')
|
|
@@ -99,12 +123,22 @@ with gr.Blocks(theme=theme, css=css) as demo:
|
|
| 99 |
axs[1].set_title(f"-{defocus_amount}")
|
| 100 |
axs[2].axis('off')
|
| 101 |
axs[2].set_title(f"Difference")
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
|
| 105 |
btn.click(on_button_click, inputs=[resolution_num], outputs=[plot_2d, plot_3d])
|
| 106 |
btn_batch.click(zernike.generate_batch, inputs=[resolution_num], outputs=[plot_batch])
|
| 107 |
resolution_num.change(on_settings_click, inputs=[resolution_num])
|
| 108 |
-
btn_diff.click(on_diff_button_click, inputs=[defocus_amt], outputs=[plot_diff])
|
| 109 |
|
| 110 |
demo.launch()
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
|
| 3 |
import gradio as gr
|
| 4 |
import matplotlib.pyplot as plt
|
| 5 |
#from fraunhofer_test import generate_diff
|
| 6 |
from zern_generator import Zernike
|
| 7 |
from fraunhofer_test import Fraunhofer
|
| 8 |
+
from PIL import Image
|
| 9 |
+
import numpy as np
|
| 10 |
+
import shutil
|
| 11 |
css = """
|
| 12 |
.container {
|
| 13 |
# height: 50vh;
|
|
|
|
| 34 |
|
| 35 |
zernike = Zernike()
|
| 36 |
fraunhofer = Fraunhofer(zernike)
|
| 37 |
+
curr_diff = None
|
| 38 |
theme = gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)
|
| 39 |
with gr.Blocks(theme=theme, css=css) as demo:
|
| 40 |
with gr.Row():
|
| 41 |
zern_sliders = []
|
|
|
|
| 42 |
with gr.Column(scale=1):
|
|
|
|
| 43 |
with gr.Tab(label="Генератор"):
|
| 44 |
|
| 45 |
+
defocus_amt = gr.Number(
|
| 46 |
+
label="Величина дефокуса",
|
| 47 |
+
value=2,
|
| 48 |
+
interactive=True
|
| 49 |
+
)
|
| 50 |
with gr.Row():
|
| 51 |
+
num_zernikes = gr.Number(
|
| 52 |
+
label="Количество коэффициентов Цернике",
|
| 53 |
+
value=6,
|
| 54 |
+
interactive=True
|
| 55 |
+
)
|
| 56 |
show_zernikes_btn = gr.Button("Показать")
|
| 57 |
sliders_container = gr.Column(elem_classes=["container"])
|
| 58 |
|
|
|
|
| 64 |
count = min(count, 100)
|
| 65 |
for i in range(count):
|
| 66 |
term_name = f" - {zernike.term[i]}" if i < len(zernike.term) else ""
|
| 67 |
+
sld = gr.Slider(
|
| 68 |
+
key=i,
|
| 69 |
+
label=f"Zernike {i+1}{term_name}",
|
| 70 |
+
minimum=-100,
|
| 71 |
+
interactive=True,
|
| 72 |
+
step=0.01,
|
| 73 |
+
value=0
|
| 74 |
+
)
|
| 75 |
|
| 76 |
sld.change(update_zerns, inputs=[gr.Number(value=i, visible=False), sld])
|
| 77 |
sliders_container.add_child(sld)
|
|
|
|
| 81 |
with gr.Tab(label="Настройки"):
|
| 82 |
resolution_num = gr.Number(value=256, label="Разрешение")
|
| 83 |
|
|
|
|
| 84 |
|
| 85 |
with gr.Column(scale=5):
|
| 86 |
with gr.Tab(label="Экран"):
|
|
|
|
| 93 |
btn_batch = gr.Button("Рассчитать тестовые экраны")
|
| 94 |
with gr.Tab(label="Разница у фокуса"):
|
| 95 |
plot_diff = gr.Plot(label="Разница в фокусе")
|
| 96 |
+
|
| 97 |
btn_diff = gr.Button("Рассчитать разницу в фокусе")
|
| 98 |
+
file_download = gr.File(label="Скачать")
|
| 99 |
|
| 100 |
def on_button_click(resolution):
|
| 101 |
return zernike.generate_zern_wavefront_fig(*[zerns[key] for key in sorted(zerns)])
|
|
|
|
| 103 |
def on_settings_click(resolution):
|
| 104 |
print(resolution)
|
| 105 |
zernike.set_image_params(npix=resolution)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
|
| 110 |
def on_diff_button_click(defocus_amount):
|
| 111 |
+
shutil.rmtree("temp", ignore_errors=True)
|
| 112 |
+
os.makedirs("temp")
|
| 113 |
+
global curr_diff
|
| 114 |
pl, mn, diff = fraunhofer.generate_diff(defocus_amount, *[zerns[key] for key in sorted(zerns)])
|
| 115 |
+
curr_diff = diff
|
| 116 |
fig, axs = plt.subplots(1, 3, figsize = (20, 10))
|
| 117 |
axs[0].imshow(pl, cmap='grey')
|
| 118 |
axs[1].imshow(mn, cmap='grey')
|
|
|
|
| 123 |
axs[1].set_title(f"-{defocus_amount}")
|
| 124 |
axs[2].axis('off')
|
| 125 |
axs[2].set_title(f"Difference")
|
| 126 |
+
|
| 127 |
+
a = np.min(curr_diff)
|
| 128 |
+
b = np.max(curr_diff)
|
| 129 |
+
img_arr = ((curr_diff - a) / (b - a) * 255).astype(np.uint8)
|
| 130 |
+
img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
|
| 131 |
+
z = [str(zerns[key]) for key in sorted(zerns)]
|
| 132 |
+
|
| 133 |
+
filename = f'temp/{"_".join(z[1:])}.png'
|
| 134 |
+
img.save(filename)
|
| 135 |
+
|
| 136 |
+
return fig, filename
|
| 137 |
|
| 138 |
|
| 139 |
btn.click(on_button_click, inputs=[resolution_num], outputs=[plot_2d, plot_3d])
|
| 140 |
btn_batch.click(zernike.generate_batch, inputs=[resolution_num], outputs=[plot_batch])
|
| 141 |
resolution_num.change(on_settings_click, inputs=[resolution_num])
|
| 142 |
+
btn_diff.click(on_diff_button_click, inputs=[defocus_amt], outputs=[plot_diff, file_download])
|
| 143 |
|
| 144 |
demo.launch()
|
fraunhofer_test.py
CHANGED
|
@@ -2,7 +2,9 @@ import matplotlib.pyplot as plt
|
|
| 2 |
import cupy as cp
|
| 3 |
import numpy as np
|
| 4 |
import math
|
| 5 |
-
from
|
|
|
|
|
|
|
| 6 |
from zern_generator import Zernike
|
| 7 |
|
| 8 |
|
|
@@ -10,7 +12,7 @@ def denoise(screen: np.ndarray):
|
|
| 10 |
return np.where(np.abs(screen) < 1e-4, 0, screen)
|
| 11 |
|
| 12 |
|
| 13 |
-
class
|
| 14 |
def __init__(self, zernike: Zernike):
|
| 15 |
self.focal_distance = 100 * 10 ** -3
|
| 16 |
self.distance = 100 * 10 ** -3
|
|
@@ -21,17 +23,15 @@ class Fraunhofer:
|
|
| 21 |
|
| 22 |
self.zernike = zernike
|
| 23 |
|
| 24 |
-
# def _denoise(screen: np.ndarray):
|
| 25 |
-
# return np.where(np.abs(screen) < 1e-4, 0, screen)
|
| 26 |
|
| 27 |
def get_focal_point(self,input_screen):
|
| 28 |
input_screen_gpu = cp.asarray(input_screen)
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
U_fraun =
|
| 33 |
-
|
| 34 |
-
|
| 35 |
I_fraun = cp.abs(U_fraun)**2
|
| 36 |
return I_fraun / cp.max(I_fraun)
|
| 37 |
|
|
@@ -52,11 +52,108 @@ class Fraunhofer:
|
|
| 52 |
focal_image_plus = denoise(self.get_focal_point(wf_c*cp.exp(f_plus_c * 1j)))
|
| 53 |
focal_image_minus = denoise(self.get_focal_point(wf_c*cp.exp(f_minus_c * 1j)))
|
| 54 |
|
|
|
|
| 55 |
return (
|
| 56 |
cp.asnumpy(focal_image_plus),
|
| 57 |
cp.asnumpy(focal_image_minus),
|
| 58 |
cp.asnumpy(focal_image_plus - focal_image_minus)
|
| 59 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
|
|
|
| 2 |
import cupy as cp
|
| 3 |
import numpy as np
|
| 4 |
import math
|
| 5 |
+
from numpy.fft import fft2, fftshift, ifftshift
|
| 6 |
+
from cupyx.scipy import fft as fft_gpu
|
| 7 |
+
|
| 8 |
from zern_generator import Zernike
|
| 9 |
|
| 10 |
|
|
|
|
| 12 |
return np.where(np.abs(screen) < 1e-4, 0, screen)
|
| 13 |
|
| 14 |
|
| 15 |
+
class FraunhoferGPU:
|
| 16 |
def __init__(self, zernike: Zernike):
|
| 17 |
self.focal_distance = 100 * 10 ** -3
|
| 18 |
self.distance = 100 * 10 ** -3
|
|
|
|
| 23 |
|
| 24 |
self.zernike = zernike
|
| 25 |
|
|
|
|
|
|
|
| 26 |
|
| 27 |
def get_focal_point(self,input_screen):
|
| 28 |
input_screen_gpu = cp.asarray(input_screen)
|
| 29 |
+
xv = cp.asarray(self.zernike.xv)
|
| 30 |
+
yv = cp.asarray(self.zernike.yv)
|
| 31 |
+
phase_mul = ((cp.exp(1j*self.k*self.distance) * cp.exp(1j*self.k*(xv**2 + yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
|
| 32 |
+
U_fraun = fft_gpu.fft2(fft_gpu.ifftshift(input_screen_gpu), overwrite_x=True)
|
| 33 |
+
U_fraun = fftshift(U_fraun * phase_mul)
|
| 34 |
+
|
| 35 |
I_fraun = cp.abs(U_fraun)**2
|
| 36 |
return I_fraun / cp.max(I_fraun)
|
| 37 |
|
|
|
|
| 52 |
focal_image_plus = denoise(self.get_focal_point(wf_c*cp.exp(f_plus_c * 1j)))
|
| 53 |
focal_image_minus = denoise(self.get_focal_point(wf_c*cp.exp(f_minus_c * 1j)))
|
| 54 |
|
| 55 |
+
|
| 56 |
return (
|
| 57 |
cp.asnumpy(focal_image_plus),
|
| 58 |
cp.asnumpy(focal_image_minus),
|
| 59 |
cp.asnumpy(focal_image_plus - focal_image_minus)
|
| 60 |
)
|
| 61 |
+
|
| 62 |
+
class Fraunhofer:
|
| 63 |
+
def __init__(self, zernike: Zernike):
|
| 64 |
+
self.focal_distance = 100 * 10 ** -3
|
| 65 |
+
self.distance = 100 * 10 ** -3
|
| 66 |
+
self.radius = 5 * 10 ** -3
|
| 67 |
+
self.span = (-(10 ** -2), 10 ** -2)
|
| 68 |
+
self.wavelength = 500 * 10 ** -9
|
| 69 |
+
self.k = 2*math.pi/self.wavelength
|
| 70 |
+
|
| 71 |
+
self.zernike = zernike
|
| 72 |
+
|
| 73 |
+
# def _denoise(screen: np.ndarray):
|
| 74 |
+
# return np.where(np.abs(screen) < 1e-4, 0, screen)
|
| 75 |
+
|
| 76 |
+
def get_focal_point(self,input_screen):
|
| 77 |
+
input_screen_gpu = np.asarray(input_screen)
|
| 78 |
+
phase_mul = ((np.exp(1j*self.k*self.distance) * np.exp(1j*self.k*(self.zernike.xv**2 + self.zernike.yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
|
| 79 |
+
U_fraun = fft2(ifftshift(input_screen_gpu))
|
| 80 |
+
U_fraun = fftshift(U_fraun * phase_mul)
|
| 81 |
+
#U_fraun = fftshift(U_fraun)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
I_fraun = np.abs(U_fraun)**2
|
| 85 |
+
return I_fraun / np.max(I_fraun)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def generate_diff(self, defocus_amount, *zernikes):
|
| 89 |
+
zernikes = list(zernikes)
|
| 90 |
+
if len(zernikes) < 5:
|
| 91 |
+
zernikes += [0] * (5-len(zernikes))
|
| 92 |
+
|
| 93 |
+
wf = self.zernike.generate_zern_screen([1], self.radius)
|
| 94 |
+
|
| 95 |
+
f_plus = self.zernike.generate_zern_screen(
|
| 96 |
+
self.zernike.add_defocus(defocus_amount,zernikes),
|
| 97 |
+
norm_radius=self.radius
|
| 98 |
+
)
|
| 99 |
+
f_minus = self.zernike.generate_zern_screen(
|
| 100 |
+
self.zernike.add_defocus(-defocus_amount,zernikes),
|
| 101 |
+
norm_radius=self.radius
|
| 102 |
+
)
|
| 103 |
+
|
| 104 |
+
wf_c = np.asarray(wf)
|
| 105 |
+
f_plus_c = np.asarray(f_plus)
|
| 106 |
+
f_minus_c = np.asarray(f_minus)
|
| 107 |
+
focal_image_plus = denoise(
|
| 108 |
+
self.get_focal_point(wf_c*np.exp(f_plus_c * 1j))
|
| 109 |
+
)
|
| 110 |
+
focal_image_minus = denoise(
|
| 111 |
+
self.get_focal_point(wf_c*np.exp(f_minus_c * 1j))
|
| 112 |
+
)
|
| 113 |
+
diff = focal_image_plus - focal_image_minus
|
| 114 |
+
normalized_diff = diff / cp.max(diff)
|
| 115 |
+
|
| 116 |
+
return (
|
| 117 |
+
cp.asnumpy(focal_image_plus),
|
| 118 |
+
cp.asnumpy(focal_image_minus),
|
| 119 |
+
cp.asnumpy(normalized_diff)
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
|
| 123 |
|
| 124 |
+
if __name__ == "__main__":
|
| 125 |
+
zernike = Zernike()
|
| 126 |
+
zernike.set_image_params(npix=2 ** 8)
|
| 127 |
+
zoom_factor = 20
|
| 128 |
+
f = Fraunhofer(zernike=zernike)
|
| 129 |
+
ratio = (f.wavelength*f.focal_distance)/f.radius
|
| 130 |
+
zernikes = [[1 if i == j else 0 for i in range(0,24)] for j in range(20,24)]
|
| 131 |
+
print(zernikes)
|
| 132 |
+
fig, ax = plt.subplots(4,1)
|
| 133 |
+
for i, z in enumerate(zernikes):
|
| 134 |
+
print(zernike._osa_to_noll_list(z))
|
| 135 |
+
wf_a = zernike.generate_zern_screen([1], 0.01/zoom_factor)
|
| 136 |
+
wf_c = zernike.generate_zern_screen(z, 0.01/zoom_factor)
|
| 137 |
+
wf_c_nz = zernike.generate_zern_screen(z, 0.01)
|
| 138 |
+
wf = wf_a * np.exp(wf_c*1j)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
focal = f.get_focal_point(wf)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
zoom = ratio*zoom_factor
|
| 146 |
+
#ax[i][0].imshow(np.abs(wf_c_nz))
|
| 147 |
+
|
| 148 |
+
ax[i].imshow(np.abs(focal))
|
| 149 |
+
ax[i].imshow(np.abs(focal))
|
| 150 |
+
ax[0].set_title("Zernike 5 - DEFOCUS")
|
| 151 |
+
ax[1].set_title("Zernike 6 - V-PR-ASTIGMATISM")
|
| 152 |
+
ax[2].set_title("Zernike 7 - V-TREFOIL")
|
| 153 |
+
ax[3].set_title("Zernike 8 - V-PR_COMA")
|
| 154 |
+
ax[0].axis('off')
|
| 155 |
+
ax[1].axis('off')
|
| 156 |
+
ax[2].axis('off')
|
| 157 |
+
ax[3].axis('off')
|
| 158 |
+
plt.show()
|
| 159 |
|
generate_dataset.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
from zern_generator import Zernike
|
| 2 |
from PIL import Image
|
| 3 |
-
from fraunhofer_test import Fraunhofer
|
| 4 |
import cupy as cp
|
| 5 |
import matplotlib.pyplot as plt
|
| 6 |
import itertools
|
|
@@ -12,69 +12,40 @@ import numpy as np
|
|
| 12 |
|
| 13 |
zernike = Zernike()
|
| 14 |
zernike.set_image_params(npix=2 ** 8)
|
| 15 |
-
fraunhofer =
|
| 16 |
|
| 17 |
|
| 18 |
-
def generate_image(z):
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
start_time = time()
|
| 22 |
arr = fraunhofer.generate_diff(1, 0, *z)
|
| 23 |
a = cp.min(arr[2])
|
| 24 |
b = cp.max(arr[2])
|
| 25 |
img_arr = ((arr[2] - a) / (b - a) * 255).astype(cp.uint8)
|
| 26 |
img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
def generate_dataset(zs):
|
| 46 |
-
c = 0
|
| 47 |
-
window_size = 50
|
| 48 |
-
times = []
|
| 49 |
-
start_time = time()
|
| 50 |
-
total_images = len(zs)
|
| 51 |
num_workers = 24
|
| 52 |
if num_workers is None:
|
| 53 |
num_workers = cpu_count()
|
| 54 |
|
| 55 |
with Pool(num_workers) as pool:
|
| 56 |
results = []
|
| 57 |
-
|
| 58 |
for result in pool.imap_unordered(generate_image, zs):
|
| 59 |
-
c += 1
|
| 60 |
-
|
| 61 |
results.append(result)
|
| 62 |
-
|
| 63 |
-
current_time = time()
|
| 64 |
-
iteration_time = current_time - start_time
|
| 65 |
-
times.append(iteration_time)
|
| 66 |
-
if len(times) > window_size:
|
| 67 |
-
times.pop(0)
|
| 68 |
-
avg_iteration_time = sum(times) / len(times)
|
| 69 |
-
|
| 70 |
-
# if c % 10 == 0:
|
| 71 |
-
# os.system('cls')
|
| 72 |
-
# print(f"Generated {c}/{total_images}")
|
| 73 |
-
# elapsed_time = current_time - start_time
|
| 74 |
-
# print(f"Elapsed time: {elapsed_time:.2f} s")
|
| 75 |
-
# remaining_images = total_images - c
|
| 76 |
-
# estimated_remaining_time = avg_iteration_time * remaining_images
|
| 77 |
-
# print(f"Estimated remaining time: {estimated_remaining_time:.2f} s")
|
| 78 |
for result in results:
|
| 79 |
result.get()
|
| 80 |
|
|
@@ -92,22 +63,33 @@ def generate_dataset_gpu(zs):
|
|
| 92 |
for z in zs:
|
| 93 |
|
| 94 |
generate_image(z)
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
rng = (-5, 5)
|
| 99 |
-
step = 0.5
|
| 100 |
-
points = tuple(np.linspace(*rng, int((rng[1] - rng[0]) / step + 1)))
|
| 101 |
points_as_tuples = tuple(float(x) for x in points)
|
|
|
|
| 102 |
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
#
|
| 106 |
-
#
|
| 107 |
-
# for
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from zern_generator import Zernike
|
| 2 |
from PIL import Image
|
| 3 |
+
from fraunhofer_test import Fraunhofer, FraunhoferGPU
|
| 4 |
import cupy as cp
|
| 5 |
import matplotlib.pyplot as plt
|
| 6 |
import itertools
|
|
|
|
| 12 |
|
| 13 |
zernike = Zernike()
|
| 14 |
zernike.set_image_params(npix=2 ** 8)
|
| 15 |
+
fraunhofer = FraunhoferGPU(zernike)
|
| 16 |
|
| 17 |
|
| 18 |
+
def generate_image(z, group_depth):
|
|
|
|
|
|
|
|
|
|
| 19 |
arr = fraunhofer.generate_diff(1, 0, *z)
|
| 20 |
a = cp.min(arr[2])
|
| 21 |
b = cp.max(arr[2])
|
| 22 |
img_arr = ((arr[2] - a) / (b - a) * 255).astype(cp.uint8)
|
| 23 |
img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
|
| 24 |
+
|
| 25 |
+
coeffs = '_'.join([f'{x:.2f}' for x in z[group_depth:]])
|
| 26 |
+
group = "/".join([str(x) for x in z[:group_depth]])
|
| 27 |
+
path = f'./screens_tst/{group}'
|
| 28 |
+
if not os.path.exists(path):
|
| 29 |
+
try:
|
| 30 |
+
os.makedirs(path)
|
| 31 |
+
except:
|
| 32 |
+
print("Directory already exists. Skipping.")
|
| 33 |
+
filename = f'{path}/{coeffs}_.png'
|
| 34 |
+
img.save(filename)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def generate_dataset(range, step, kf_cnt):
|
| 40 |
+
zs = get_zernike_coeffs(range, step, kf_cnt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
num_workers = 24
|
| 42 |
if num_workers is None:
|
| 43 |
num_workers = cpu_count()
|
| 44 |
|
| 45 |
with Pool(num_workers) as pool:
|
| 46 |
results = []
|
|
|
|
| 47 |
for result in pool.imap_unordered(generate_image, zs):
|
|
|
|
|
|
|
| 48 |
results.append(result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
for result in results:
|
| 50 |
result.get()
|
| 51 |
|
|
|
|
| 63 |
for z in zs:
|
| 64 |
|
| 65 |
generate_image(z)
|
| 66 |
+
|
| 67 |
+
def get_zernike_coeffs(range, step, kf_cnt):
|
| 68 |
+
points = tuple(np.linspace(*range, int((range[1] - range[0]) / step + 1)))
|
|
|
|
|
|
|
|
|
|
| 69 |
points_as_tuples = tuple(float(x) for x in points)
|
| 70 |
+
return np.array(list(set(itertools.product(points_as_tuples, repeat=kf_cnt))))
|
| 71 |
|
| 72 |
+
if __name__ == '__main__':
|
| 73 |
+
# rng = (-5, 5)
|
| 74 |
+
# step = 0.5
|
| 75 |
+
# points = tuple(np.linspace(*rng, int((rng[1] - rng[0]) / step + 1)))
|
| 76 |
+
# points_as_tuples = tuple(float(x) for x in points)
|
| 77 |
+
|
| 78 |
+
zernikes = get_zernike_coeffs((-5,5), 0.25, 2)
|
| 79 |
+
|
| 80 |
+
print("Total images: ", len(zernikes))
|
| 81 |
+
total_gen_time, total_save_time = 0, 0
|
| 82 |
+
start = time()
|
| 83 |
+
for i, z in enumerate(zernikes):
|
| 84 |
+
generate_image(z, 1)
|
| 85 |
+
if i % 100 == 0:
|
| 86 |
+
print(f"{i}/{len(zernikes)}")
|
| 87 |
+
print("Average generation time: ", (time()-start)/len(zernikes))
|
| 88 |
+
|
| 89 |
+
# generate_dataset(zernikes)
|
| 90 |
+
# last = 1
|
| 91 |
+
# for i in range(1,6):
|
| 92 |
+
|
| 93 |
+
# p = get_zernike_coeffs([-5,5], 0.25, i)
|
| 94 |
+
# print(f"Количество коэфф-ов: {i} -> Количество комбинаций: {len(p)}")
|
| 95 |
+
# last = len(p)
|
zern_generator.py
CHANGED
|
@@ -56,10 +56,12 @@ class Zernike:
|
|
| 56 |
degree = math.ceil((-3 + math.sqrt(8 * num_zerns + 1)) / 2)
|
| 57 |
zerns = list(zerns) + [0] * int((((degree + 1) * (degree + 2) / 2) - len(zerns)))
|
| 58 |
cart = RZern(degree)
|
| 59 |
-
|
|
|
|
| 60 |
cart.make_cart_grid(self.xv / norm_radius, self.yv / norm_radius)
|
| 61 |
-
|
| 62 |
-
screen =
|
|
|
|
| 63 |
screen[mask == 0] = 0
|
| 64 |
screen[np.isnan(screen)] = 0
|
| 65 |
return screen
|
|
@@ -113,7 +115,6 @@ class Zernike:
|
|
| 113 |
first = (n * (n + 1)) // 2
|
| 114 |
second = abs(m)
|
| 115 |
third = 0
|
| 116 |
-
# I wanted to simplify the logic but it seems to work like a colander
|
| 117 |
if m > 0 and n % 4 in [0, 1]:
|
| 118 |
third = 0
|
| 119 |
elif m < 0 and n % 4 in [2, 3]:
|
|
@@ -129,11 +130,16 @@ class Zernike:
|
|
| 129 |
return self._mn_to_noll(*self._osa_to_mn(idx))
|
| 130 |
|
| 131 |
def _osa_to_noll_list(self, zernikes):
|
| 132 |
-
indexed_zerns = sorted(
|
|
|
|
|
|
|
|
|
|
| 133 |
used_indeces = [x for x, _ in indexed_zerns]
|
| 134 |
mn, mx = min(used_indeces), max(used_indeces)
|
| 135 |
missing_indeces = set(range(mn, mx + 1)) - set(used_indeces)
|
| 136 |
-
return [x[1] for x in
|
|
|
|
|
|
|
| 137 |
|
| 138 |
|
| 139 |
term = ["PISTON", "V-TILT", "H-TILT", "DEFOCUS", "O-PR-ASTIGMATISM", "V-PR-ASTIGMATISM", "V-PR-COMA", "H-PR-COMA",
|
|
|
|
| 56 |
degree = math.ceil((-3 + math.sqrt(8 * num_zerns + 1)) / 2)
|
| 57 |
zerns = list(zerns) + [0] * int((((degree + 1) * (degree + 2) / 2) - len(zerns)))
|
| 58 |
cart = RZern(degree)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
cart.make_cart_grid(self.xv / norm_radius, self.yv / norm_radius)
|
| 62 |
+
|
| 63 |
+
screen = cart.eval_grid(np.array(zerns), matrix=True)
|
| 64 |
+
screen = np.array(screen)
|
| 65 |
screen[mask == 0] = 0
|
| 66 |
screen[np.isnan(screen)] = 0
|
| 67 |
return screen
|
|
|
|
| 115 |
first = (n * (n + 1)) // 2
|
| 116 |
second = abs(m)
|
| 117 |
third = 0
|
|
|
|
| 118 |
if m > 0 and n % 4 in [0, 1]:
|
| 119 |
third = 0
|
| 120 |
elif m < 0 and n % 4 in [2, 3]:
|
|
|
|
| 130 |
return self._mn_to_noll(*self._osa_to_mn(idx))
|
| 131 |
|
| 132 |
def _osa_to_noll_list(self, zernikes):
|
| 133 |
+
indexed_zerns = sorted(
|
| 134 |
+
map(lambda x: (self._osa_to_noll(x[0]), x[1]), enumerate(zernikes)),
|
| 135 |
+
key=lambda x: x[0]
|
| 136 |
+
)
|
| 137 |
used_indeces = [x for x, _ in indexed_zerns]
|
| 138 |
mn, mx = min(used_indeces), max(used_indeces)
|
| 139 |
missing_indeces = set(range(mn, mx + 1)) - set(used_indeces)
|
| 140 |
+
return [x[1] for x in
|
| 141 |
+
list(sorted(indexed_zerns + [(x, 0) for x in missing_indeces]))
|
| 142 |
+
]
|
| 143 |
|
| 144 |
|
| 145 |
term = ["PISTON", "V-TILT", "H-TILT", "DEFOCUS", "O-PR-ASTIGMATISM", "V-PR-ASTIGMATISM", "V-PR-COMA", "H-PR-COMA",
|