加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
result.py 4.33 KB
一键复制 编辑 原始数据 按行查看 历史
芽原基 提交于 2024-02-01 20:49 . 二稿,大量优化,函数拆分
#result.py
import numpy as np
import pkg_resources
import matplotlib.pyplot as plt
from numpy.fft import fftshift, fft2, ifftshift, fftfreq, ifft2
def generate_result(sin_val, n_val, wavelength_val, m, b, op_status):
"""
生成计算结果图
参数:
sin_val (float): 传入的 sin 值
n_val (float): 传入的折射率值
wavelength_val (float): 传入的波长值
m (int): 传入的 m 值,0 为相干光,1 为非相干光
b (int): 传入的 b 值, 0 为不启用 OPC,1 为启用 OPC
op_status (int): 0 表示第二行输出光强分布,1 表示输出图像边界
返回:
fig (matplotlib.figure.Figure): Matplotlib 图形容器
"""
# 固定参数
aperture_diameter = focal_length = 1.0
# 计算入射角 theta
theta = np.arcsin(sin_val)
# 计算数值孔径
NA = n_val * np.sin(theta)
# 波长
wavelength = wavelength_val
# 计算透镜孔径 D
lens_aperture = 2 * focal_length * np.tan(theta)
# 实空间坐标架、动量空间坐标架及光学传递函数
num_samples = 100 # 一个维度的采样数
p = 1 # 修正离散化导致的误差
num_samples_extended = (2 * p + 1) * num_samples
spatial_x = np.linspace(-0.6 * aperture_diameter, 0.6 * aperture_diameter, num_samples)
spatial_y = spatial_x.copy()
spatial_X, spatial_Y = np.meshgrid(spatial_x, spatial_y)
spatial_Y = spatial_Y[::-1, :]
kx = fftshift(fftfreq(num_samples_extended,1.2*aperture_diameter*(2*p+1)/num_samples_extended))
ky = kx.copy()
Kx, Ky = np.meshgrid(kx, ky)
k = np.sqrt(Kx**2 + Ky**2)
K = 2 * np.pi * NA / wavelength
optical_transfer_function = np.zeros((2, num_samples_extended, num_samples_extended))
optical_transfer_function[0][0:num_samples_extended][0:num_samples_extended] = k <= K
for i in range(num_samples_extended):
for j in range(num_samples_extended):
if k[i][j] < K:
optical_transfer_function[1][i][j] = np.arccos(k[i][j] / 2 / K) - k[i][j] / 2 / K * np.sqrt(1 - (k[i][j] / 2 / K)**2)
# 加载文件
file_path = pkg_resources.resource_filename(__name__, "mask.npy")
amask = np.load(file_path)
bmask=np.zeros((num_samples_extended,num_samples_extended))
def calculate_intensity(mask):
bmask[p*num_samples:(p+1)*num_samples:1,p*num_samples:(p+1)*num_samples:1]=mask
diffracted = fftshift(fft2(ifftshift(bmask)))
transmitted=diffracted*optical_transfer_function[m]
E=fftshift(ifft2(ifftshift(transmitted)))
intensity=np.abs(E)**2
output=np.zeros((num_samples,num_samples))
output=intensity[p*num_samples:(p+1)*num_samples,p*num_samples:(p+1)*num_samples]
return output/output.max()
def calculate_pixel_error(T, threshold, mask):
mp = np.zeros((num_samples, num_samples))
mp[calculate_intensity(T) > threshold] = 1
return np.sum(np.abs(mp - mask).reshape(num_samples**2, 1))
def calculate_contour(T):
res = 1
i = 0
temp = num_samples**2
while i <= 35:
t = 0.4 - 0.01 * i
if calculate_pixel_error(T, t, T) <= temp:
temp = calculate_pixel_error(T, t, T)
res = t
i = i + 1
Im = calculate_intensity(T)
edge = np.zeros((num_samples, num_samples))
edge[Im > res] = 1
return edge
# 创建 Matplotlib 图形容器,祖传配方3:1
fig, axs = plt.subplots(1, 5, figsize=(12, 4))
# 绘制光强分布或者图像边界,根据op_status决定
for i in range(5):
if op_status == 0:
intensity = calculate_intensity(amask[i + 5 * b])
axs[i].imshow(intensity, cmap='viridis', extent=(spatial_x.min(), spatial_x.max(), spatial_y.min(), spatial_y.max()))
axs[i].set_title(f'Intensity {i}')
else:
axs[i].imshow(calculate_contour(amask[i + 5 * b]), cmap='gray', extent=(spatial_x.min(), spatial_x.max(), spatial_y.min(), spatial_y.max()))
axs[i].set_title(f'Contour {i}')
# 调整子图布局
plt.tight_layout()
return fig # 返回 Matplotlib 图形容器
# 计算结果图函数调用示例
#plotter = generate_result(0.9, 1, 2.0, 1, 0, 0)
#plt.show()
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化