光学仿真在现代光学工程中扮演着越来越重要的角色,它让我们能够在计算机上模拟光在各种光学元件中的传播行为,大大降低了实验成本和开发周期。4f系统作为光学信息处理中的经典配置,由两个焦距为f的透镜和中间的自由空间组成,输入面到第一个透镜的距离为f,两个透镜之间的距离为2f,第二个透镜到输出面的距离也是f。
这种对称结构之所以重要,是因为它能在输出面完美重现输入面的光场分布(不考虑尺度变化)。理解4f系统的工作原理,不仅对光学设计至关重要,也是掌握更复杂光学系统的基础。在MATLAB中实现4f系统的仿真,我们需要解决三个核心问题:如何描述光波通过自由空间的传播(菲涅尔衍射)、如何模拟透镜对光波的调制作用,以及如何高效地进行这些计算。
透镜之所以能够聚焦光线,是因为它通过厚度变化引入了相位延迟。根据几何光学,一个理想薄透镜的相位变换函数可以表示为:
H(x,y) = exp[-iπ/(λf)(x² + y²)]
其中λ是光波长,f是透镜焦距,x和y是透镜面上的坐标。这个二次相位因子使得平面波经过透镜后会聚到焦点。
在MATLAB中实现这个相位变换时,首先需要建立空间网格。网格的范围和分辨率选择至关重要:
matlab复制lambda = 532e-9; % 绿光波长,单位米
f = 0.5; % 透镜焦距,单位米
N = 512; % 采样点数
L = 0.02; % 模拟区域大小,20mm
[x,y] = meshgrid(linspace(-L/2,L/2,N)); % 生成对称空间网格
基于上述网格,透镜传递函数可以这样计算:
matlab复制H_lens = exp(-1i*pi/(lambda*f)*(x.^2 + y.^2));
这里有几个关键细节需要注意:
网格间距Δx = L/N必须足够小,以满足采样定理。对于快速变化的相位函数,通常要求Δx < λf/(2L),否则会出现相位混叠(aliasing)现象。
在实际应用中,我们经常需要对透镜函数进行裁剪,只保留有效孔径内的部分:
matlab复制aperture = (x.^2 + y.^2) <= (D/2)^2; % D为透镜直径
H_lens = H_lens .* aperture;
matlab复制H_lens2 = conj(H_lens);
注意:透镜函数的相位符号与传播方向定义有关。如果发现仿真结果异常(如光线发散而非聚焦),首先检查相位函数的符号是否正确。
菲涅尔衍射描述了光波在自由空间中的传播过程,其数学表达式为卷积积分:
U(x,y,z) = U(x,y,0) * h(x,y,z)
其中h(x,y,z)是菲涅尔衍射核。直接计算这个卷积计算量很大,但根据卷积定理,时域卷积等于频域乘积,我们可以利用FFT来高效计算。
菲涅尔衍射的传递函数在频域表示为:
H(u,v) = exp(ikz) exp[-iπλz(u² + v²)]
其中k=2π/λ,u和v是空间频率坐标。
基于上述理论,菲涅尔传播函数可以这样实现:
matlab复制function Uout = fresnel_prop(Uin, L, lambda, z)
[M,N] = size(Uin);
df = 1/L; % 频率间隔
u = fftshift((-M/2:M/2-1)*df); % 空间频率坐标
[u,v] = meshgrid(u);
H = exp(1i*2*pi*z/lambda) .* exp(-1i*pi*lambda*z*(u.^2 + v.^2));
Uout = ifft2(fft2(Uin) .* H);
end
这个函数有几个关键点:
频率坐标的生成必须正确对应物理尺寸。fftshift确保低频在中心,这与光学中的习惯一致。
传播距离z的符号决定了传播方向。正值表示正向传播,负值表示反向传播。
输入参数L表示模拟区域的物理尺寸(单位米),必须与实际光场匹配。
常见错误:忘记对输入光场进行fftshift/ifftshift处理,导致相位计算错误。在调用此函数前,通常需要先对Uin执行fftshift。
为了保证计算精度,必须满足菲涅尔近似条件:
Δx²/(λz) << 1
以及采样条件:
Δx ≤ λz/L
在实际操作中,可以通过以下检查来验证参数设置的合理性:
计算完成后检查能量守恒:sum(abs(Uout(:)).^2)应该约等于sum(abs(Uin(:)).^2)
观察输出光场是否有明显的混叠伪影(如高频振荡或非物理的条纹)
对于长距离传播,可以考虑使用角谱法(Angular Spectrum Method)来提高精度
现在我们将透镜和菲涅尔传播组合起来,构建完整的4f系统。系统的工作流程如下:
对应的MATLAB代码实现:
matlab复制% 生成输入光场(圆形孔径为例)
[X,Y] = meshgrid(linspace(-10e-3,10e-3,512));
U0 = double(sqrt(X.^2 + Y.^2) < 2e-3);
% 第一段传播
U1 = fresnel_prop(U0, 20e-3, lambda, f);
% 第一个透镜相位调制
U2 = U1 .* H_lens;
% 第二段传播
U3 = fresnel_prop(U2, 20e-3, lambda, 2*f);
% 第二个透镜相位调制
H_lens2 = conj(H_lens); % 注意共轭
U4 = U3 .* H_lens2;
% 最终输出
Uout = fresnel_prop(U4, 20e-3, lambda, f);
正确的可视化方法对结果解读至关重要:
matlab复制figure;
subplot(121); imagesc(abs(U0).^2); title('输入光强');
subplot(122); imagesc(abs(Uout).^2); title('输出光强');
colormap hot; axis image; colorbar;
在理想情况下,输出光强应该与输入光强相同(可能有一个整体的缩放因子)。如果发现以下问题,可能的原因有:
为了验证4f系统仿真的正确性,可以采用以下方法:
4f系统的一个重要应用是光学滤波。在系统的傅里叶平面(两个透镜之间的中间平面)可以插入各种滤波器:
matlab复制% 在U3计算后加入高通滤波器
filter = ones(size(U3));
filter(abs(X)<1e-3 & abs(Y)<1e-3) = 0; % 阻挡低频成分
U3_filtered = U3 .* filter;
这种空间滤波操作可以实现边缘增强、噪声消除等图像处理功能,比数字图像处理更高效。
在实际仿真中,经常会遇到各种问题。以下是一些常见问题及其解决方法:
问题:输出光场出现周期性条纹
问题:输出图像旋转或错位
问题:仿真结果与理论不符
问题:计算速度慢
对于大型仿真或参数扫描,可以考虑以下优化方法:
matlab复制% GPU加速示例
Uin_gpu = gpuArray(Uin);
H_gpu = gpuArray(H);
Uout_gpu = ifft2(fft2(Uin_gpu) .* H_gpu);
Uout = gather(Uout_gpu);
掌握了4f系统的基本仿真方法后,可以扩展到更多实际应用场景:
例如,实现一个简单的相位对比成像:
matlab复制% 生成相位物体
phase_obj = exp(1i*0.5*pi*(sqrt(X.^2 + Y.^2) < 1e-3));
% 在傅里叶平面加入相位滤波器
filter = ones(size(U3));
filter(abs(X)<0.5e-3 & abs(Y)<0.5e-3) = 1i; % 中心区域加π/2相移
% 运行4f系统
Uout = fourf_system(phase_obj, lambda, f, L, 'filter', filter);
这种技术可以将透明的相位物体转换为可见的强度对比,广泛应用于生物显微成像。