MATLAB光学仿真:4f系统数值模拟中的菲涅尔衍射函数、透镜传递函数及衍射数值计算
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系统。整个流程就像流水线:
- 输入面光场先做自由空间传播f距离
- 经过第一个透镜
- 再传播f距离
- 经过第二个透镜
- 最后传播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的滤镜来得有成就感多了。光学仿真最迷人的地方,就是用复数运算就能模拟真实世界的光线戏法。

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



所有评论(0)