MATLAB 光学仿真,4f系统数值模拟 菲涅尔衍射函数 透镜的传递函数 衍射数值计算,根据卷积定理将菲涅尔衍射转为二维傅里叶变换的形式。

在光学仿真里,4f系统就像个魔术师——它能把输入面的光场在输出面完美重现。但实现这个魔术的关键,是咱们得搞明白光是怎么通过透镜和自由空间传播的。今天咱们用MATLAB扒开这个过程的代码实现,重点聊聊菲涅尔衍射怎么被「掰弯」成傅里叶变换。

先看透镜的相位变换操作。假设一束波长为λ的光经过焦距f的透镜,其传递函数可以用两行代码搞定:

lambda = 532e-9; % 绿光波长
f = 0.5; % 透镜焦距
[x,y] = meshgrid(-0.01:2e-4:0.01); % 生成空间网格
H_lens = exp(-1i*pi/(lambda*f)*(x.^2 + y.^2)); % 透镜相位函数

这个指数项就是透镜的相位变换核心,二次相位因子把入射波前给扭曲了。注意网格步长别太大,否则会出现相位混叠——就像拍高速旋转的电风扇叶片时出现的虚假静止效果。

接下来处理最难啃的菲涅尔衍射。传统方法要算卷积积分,但咱们用二维傅里叶变换偷懒。根据卷积定理,菲涅尔传播可以改写为:

function Uout = fresnel_prop(Uin, L, lambda, z)
    [M,N] = size(Uin);
    df = 1/(L*M); % 频率间隔
    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

这里有几个坑要注意:空间频率坐标的生成必须严格对应物理尺寸,z值的正负号影响传播方向。曾经有个哥们把z写成负数,结果光往回跑,调试了两天没合眼。

MATLAB 光学仿真,4f系统数值模拟 菲涅尔衍射函数 透镜的传递函数 衍射数值计算,根据卷积定理将菲涅尔衍射转为二维傅里叶变换的形式。

现在把这两个模块塞进4f系统。整个流程就像流水线:

  1. 输入面光场先做自由空间传播f距离
  2. 经过第一个透镜
  3. 再传播f距离
  4. 经过第二个透镜
  5. 最后传播f距离到输出面

写成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, f);

% 第二个透镜(可能需要调整相位符号)
H_lens2 = conj(H_lens); % 注意共轭
U4 = U3 .* H_lens2;

% 最终输出
Uout = fresnel_prop(U4, 20e-3, lambda, f);

运行完别急着看结果,先检查能量守恒。有次仿真结果能量翻倍,最后发现是透镜相位函数漏了负号,导致光线被「增强」而不是聚焦。

最后画图时记得取模的平方:

imagesc(abs(Uout).^2); 
colormap hot; axis image;

这时候你应该看到输入图像完美重现——除非采样率不够或者边界处理不当。有个隐藏技巧是在输入面边缘加渐变衰减,防止衍射产生的高频分量在频域里乱窜。

玩转这些代码后,可以尝试在傅里叶面加滤波器。比如把中间区域置零,你会发现输出图像边缘被锐化——这可比Photoshop的滤镜来得有成就感多了。光学仿真最迷人的地方,就是用复数运算就能模拟真实世界的光线戏法。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐