拓冰建站拓冰建站
首页 / 资讯中心 / 正文

微透镜阵列光学仿真实践:Zemax与MATLAB联调实现光场相机与波前传感器

作为常年折腾光学仿真与图像处理联调的人我看到“基于微透镜阵列的Zemax与MATLAB实现光场相机、波前传感器及Sensor的应用研究”这个题目第一反应就是这活儿我熟。微透镜阵列这玩意儿看着就是一片小透镜排排坐但真要从Zemax建模开始一路做到MATLAB里出光场重聚焦图像或者波前重构结果中间藏着的坑比很多人预想的多得多。Zemax负责跟光线打交道MATLAB负责跟数据打交道而Sensor传感器是这两个世界的接口——光信号最终变成电信号和数字矩阵后面所有算法都建立在“Sensor采样得到的数据”之上。这篇内容适合正在做光场相机或波前传感器课题的硕博生也适合刚接触微透镜阵列仿真、想在正式流片或搭建实验系统前先跑通仿真链路的光学工程师。我会把整个流程拆开揉碎从设计思路、建模参数到Zemax与MATLAB的数据交互再到我自己踩过的一些坑全部摊开来讲。1. 内容整体设计与思路拆解1.1 微透镜阵列系统的核心设计逻辑微透镜阵列在光场相机和波前传感器里的角色本质上都是在“对光束进行空间分割和采样”。光场相机用微透镜阵列把主镜头孔径的光线按方向分到Sensor的不同像素上从而记录下包含位置和方向信息的四维光场Shack-Hartmann波前传感器则是利用微透镜阵列把入射波前分割成子孔径每个子孔径聚焦到Sensor上形成光斑通过光斑质心偏移量反推波前斜率。这两类应用的物理模型有相似之处但参数取向截然不同光场相机关注的是空间分辨率和角度分辨率的平衡波前传感器关注的是子孔径内光斑的质心定位精度和动态范围。我在做这类项目时习惯先把系统链路画成一张信号流图光源或目标场景 → 主光学系统光场相机或畸变波前波前传感器 → 微透镜阵列 → Sensor采样 → 数据输出 → 算法重建。很多新手一上来就扎进Zemax里调镜头却忽略了“Sensor采样”这一步决定了后面所有算法的输入质量。比如光场相机的微透镜阵列周期与Sensor像素尺寸如果不匹配就算光学设计做得再漂亮后期在MATLAB里做数字重聚焦时也会出现严重的条纹混叠和分辨率损失。这就好比拍照片时镜头很好但感光元件分辨率不够照片细节一样出不来。这里面有一个关键取舍需要在一开始就明确光场相机是在用空间分辨率换角度分辨率。每个微透镜覆盖的像素数越多角度采样越密光场图像的视角变化范围越大但每个微透镜下的空间采样就越少最终渲染出的图像空间分辨率就越低。设计时你要决定子孔径图像的等效分辨率能够接受多少。通常微透镜覆盖的像素数取 3×3 到 15×15 之间太大的话渲染图像像素太少太小的化角度信息不足以做像差校正或深度估计。波前传感器则要考虑子孔径数量与动态范围子孔径数量越多波前采样点越密但如果每个子孔径在Sensor上的光斑偏移超出了它的单元区域质心提取就会出错甚至串扰到相邻子孔径。1.2 为什么Zemax与MATLAB双平台协同是常用搭配单靠Zemax也能完成光学仿真单靠MATLAB也能做衍射传播和图像重建但把两者组合起来才是工程上最顺手的路径。Zemax的核心优势在于物理光学建模的准确性——它的非序列模式可以精确追迹任意光线仿真微透镜阵列对光束的偏折、聚焦、散射而MATLAB的核心优势在于矩阵计算和算法开发——一旦Zemax输出PSF点扩散函数、ZBFZemax Beam File或文本数据MATLAB就能快速实现光场重聚焦、质心检测、Zernike拟合这些后续算法而且UI开发、批量数据循环分析都很方便。对做系统研究的工程师来说这种双平台协同的最大好处是“责任边界清晰”。光学设计人员在Zemax中负责回答“微透镜阵列怎么排布、焦距取多少、Sensor放在哪里”算法人员在MATLAB中负责回答“Sensor采样到的数据如何重建出光场图像或波前相位”。两边并行推进中间通过标准数据接口对接极大缩短了联调周期。我在实际项目里一般采取这样的工作顺序先在Zemax里完成光学结构设计并验证点列图和MTF再导出一组与Sensor像素网格对齐的PSF或光斑图数据然后在MATLAB里做Sensor采样建模和算法重建遇到成像质量问题回头修改Zemax中的参数如此循环迭代直到指标满足要求。1.3 Sensor在链路中的角色与参数匹配Sensor图像传感器是整个系统中的“翻译官”把光学图像变成数字信号。但它不是完美的翻译官像素尺寸、像元间距、量子效率、暗电流、读出噪声、模数转换位数都会影响最终数据的质量。在Zemax仿真中通常把Sensor简化为一个探测面可以设置像素尺寸和像素数但在MATLAB仿真中我们需要更细致地建立光电转换模型包括光子噪声泊松噪声、读取噪声高斯噪声、非均匀响应PRNU、暗电流等。这些非理想因素直接影响波前传感器的质心定位精度和光场相机的图像信噪比尤其在弱光条件下噪声对质心偏移的干扰可能达到零点几个像素对应波前方的误差就会超出设计容限。所以在做Sensor参数匹配时一定要把微透镜阵列的几何参数和Sensor参数放在一起算。以光场相机为例微透镜阵列到Sensor的距离应当等于微透镜焦距或根据设计公式决定离焦量而微透镜尺寸与Sensor像素尺寸的比值决定了角度采样数。假设Sensor像素尺寸是 p3.45μm微透镜阵元尺寸选为 D34.5μm即每边覆盖10个像素那角度分辨率就是10×10。这个参数关系在Zemax布局图上看不出问题但如果导入MATLAB做数字重聚焦时把微透镜中心和像素网格对错了重聚焦图像会出现明显的蜂窝pattern。后面我会讲到具体如何对齐。2. 微透镜阵列在Zemax中的建模与设计要点2.1 光场相机微透镜阵列建模流程在Zemax中做光场相机的微透镜阵列核心模型包括主镜头、微透镜阵列、Sensor探测面三部分。主镜头可以用标准Zemax镜头库里的双高斯或定焦镜头模型微透镜阵列在非序列模式下通常用“Array Object”或者逐个小透镜建模。如果你用的版本支持直接使用“MicroLensArray”对象会方便很多可以通过参数设置阵元数量、通光孔径、曲率半径、透镜材料与排列方式。建模时有一个重点是微透镜阵列的放置位置必须落在主镜头的像面上而不是随便放在主镜头和Sensor之间。主镜头把场景成像在某个平面微透镜阵列就在这个位置对一次像进行角度重采样然后Sensor置于微透镜阵列焦距处接收每个微透镜聚焦后的光斑。一个常见的误区是认为微透镜阵列离Sensor越近越好实际上当距离等于微透镜焦距时每个微透镜把入射光束汇聚成一个小光斑这个光斑的直径决定了角度分辨率与空间分辨率的关系如果你把间距设错了光斑尺寸与像素尺寸不匹配系统分辨率就会明显下降。参数方面我的一般设置参考如下单位mm参数数值示例说明主镜头焦距 f_main50决定视场和入瞳大小微透镜阵列周期 D0.1与Sensor像素尺寸配合决定角度采样微透镜焦距 f_MLA0.5决定Sensor位置和聚焦能力阵元数量X×Y60×60决定最终光场图像的子孔径数量Sensor像素尺寸 p0.01与D配合得到10×10角度采样Sensor像素数600×600D×角度采样数×阵列数用Zemax做非序列追迹时需要在探测面上查看辐照度图这里可以看到微透镜阵列作用后的光斑分布。注意在分析时要把“像素插值”关掉或者与Sensor真实像素尺寸保持一致否则仿真结果和实际硬件差异很大。另外Zemax里每个微透镜的曲率半径可以通过薄透镜公式换算先定焦距再根据材料折射率和口径算出曲率半径不要凭感觉填否则像差会大得离谱。2.2 波前传感器结构建模与Zernike系数表征Shack-Hartmann波前传感器的Zemax模型相对简单一般不考虑主镜头直接输入一个带有像差的波前然后经过微透镜阵列分割后在像面上形成光斑阵列。畸变波前的表征通常用Zernike多项式系数来描述比如离焦Z4、像散Z5/Z6、彗差Z7/Z8、球差Z9等。Zemax中在“System Explorer → Aperture”里设置入瞳直径在“Wavefront”或者通过自定义表面施加Zernike相位。一个实用技巧是用Zemax的“Zernike Fringe Phase”表面类型直接把Zernike系数写到表面上可以快速生成不同像差组合下的波前。之后用非序列模式放一个微透镜阵列和探测面就可以得到一组聚焦光斑阵列图。这个光斑图就是MATLAB端波前重构算法的输入。设计波前传感器微透镜阵列时有几个参数要特别留意。子孔径大小决定了波前采样的空间分辨率也决定了单个光斑在Sensor上的能量集中度。理论上每个子孔径的口径内波前可以近似为平面波所以子孔径越小波前重构的空间分辨率越高但衍射效应越强光斑越大质心提取越难。工程上一般选择子孔径尺寸使艾里斑直径在3到5个像素之间这样既保证光斑有足够多的采样点来提高质心定位精度又避免光斑过大导致相邻子孔径串扰。F数子孔径焦距与口径之比的选择则要平衡动态范围和灵敏度F数越小光斑对波前斜率变化越敏感但可测的最大波前斜率越小。2.3 Zemax导出数据的关键处理与黑盒封装技巧Zemax仿真结果的导出方式直接影响后续MATLAB处理的效率。一般有三种方式可以拿到数据文本导出探测面数据可以通过“Text Export”或“Export Data”导出为ASCII文件包含每个像素的坐标和辐照度值。这种方式最通用但文件较大比如600×600像素就是36万个数据点适合小规模分析。图像导出把辐照度图保存为PNG/BMP然后用MATLAB读取。优点是直观缺点是有损压缩如果格式选得不好或存在Gamma矫正问题做定量分析时不推荐。ZBF/ZMX接口或APIZemax支持通过DDE、ZOS-API与外部程序动态交互可以实时获取分析结果。这是做批量参数扫描和自动优化的最佳途径后面我会展开讲。关于“黑盒文件”这个热词它是Zemax中保护光学设计知识产权的一种方式可以将镜头设计封装成黑盒让外部使用者看不到具体结构但能正常追迹光线和做像质分析。如果你在项目交付时需要保留核心设计数据又希望合作方或客户能在Zemax中正常使用你的微透镜阵列模块就可以用“Export Black Box”导出黑盒文件。我自己用下来觉得黑盒文件对光线追迹结果的影响几乎可以忽略但要注意它在某些分析功能上有限制比如不能查看详细的系统结构参数也不能进行特定类型的优化。在导出数据前Zemax里最好先把探测面的分辨率设置成与真实Sensor像素网格一致这样后续在MATLAB中不需要重采样。还有一个细节是调整“Pixel Size”时要注意“Index of Refraction”设置部分版本在探测面属性里会有折射率选项如果默认设成1而前面有介质可能会影响仿真精度。3. MATLAB端的数据处理与核心算法实现3.1 用MATLAB读取Zemax光斑数据并做传感器采样建模Zemax输出的光斑辐照度数据只是一幅连续光强分布图真实Sensor采样会有像素积分、噪声和量化。在MATLAB里我会首先把Zemax导出的辐照度图按Sensor像素尺寸积分相当于模拟每个像素接收到的光子数。这一步通常用imresize或分块求和实现注意积分的方式对结果影响很大如果只是简单取中心点等效于忽略像素面积对后续质心计算会造成系统偏差。接着加入噪声模型。光子噪声符合泊松分布读取噪声符合高斯分布暗电流则表现为与曝光时间和温度相关的背景信号。对于波前传感器质心定位精度主要受光子噪声和读出噪声限制。可以用下面这段代码模拟含噪光斑图% 读取Zemax导出的辐照度数据模拟Sensor采样 psf load(zemax_spot.txt); % Zemax导出的光斑数据 psf psf / sum(psf(:)) * 1e6; % 换算成光子数假设总光子数1e6 noisy poissrnd(psf); % 光子噪声 noisy noisy randn(size(psf)) * 20; % 读出噪声标准差20个电子 noisy(noisy 0) 0; % 中心化质心计算 [Y, X] meshgrid(1:size(psf,2), 1:size(psf,1)); total sum(noisy(:)); cx sum(sum(noisy .* X)) / total; cy sum(sum(noisy .* Y)) / total;质心偏移量cx, cy减去无像差时的参考质心位置就可以得到该子孔径内的波前斜率。这里有一步需要非常小心Zemax导出的数据坐标系与MATLAB的数组索引坐标系方向可能不一致常见是Y轴上下翻转最好先画出来对比一下否则所有斜率方向都会反重构出的波前形状会变成镜像。3.2 光场相机的数字重聚焦实现与微透镜中心校准光场相机的原始数据是微透镜阵列下的子图像阵列在MATLAB中处理时有两种路线。一种是先提取每个微透镜下的子图像排列成四维光场L(u,v,s,t)再做数字重聚焦另一种是直接在原始图像上做积分偏移。我个人推荐第一种因为四维光场表达更灵活不仅支持重聚焦还能做全焦点合成、深度估计和视差计算。光场的提取代码大致如下% 假设原始Sensor图像为rawImg微透镜周期为N_pixels N_pixels 10; % 每个微透镜覆盖10x10像素 N_lens_y size(rawImg,1) / N_pixels; N_lens_x size(rawImg,2) / N_pixels; lightField zeros(N_pixels, N_pixels, N_lens_y, N_lens_x); for ly 1:N_lens_y for lx 1:N_lens_x block rawImg((ly-1)*N_pixels1:ly*N_pixels, ... (lx-1)*N_pixels1:lx*N_pixels); lightField(:,:,ly,lx) block; end end但这里有个致命细节微透镜阵列在物理安装时不可能与Sensor像素行列完全平行且对齐实际总会有几个像素的旋转和平移偏差。在仿真阶段可以假设对齐但在真实系统中必须在MATLAB里做几何校准否则重聚焦图像会模糊。校准方法可以使用白板采集一幅均匀光照图这时每个微透镜下的光斑中心就是微透镜的投影位置检测所有光斑中心之后用多项式拟合出微透镜网格的映射关系再对原始图像做逆变换重采样。数字重聚焦的公式说起来也简单要把光场聚焦到不同的深度等价于对四维光场在方向维上做积分同时子孔径图像按偏移量叠加。用MATLAB实现时可以通过circshift或仿射变换完成但我建议用interp2进行亚像素精度偏移否则重聚焦图像在非整数倍偏移时会出现锯齿。3.3 波前重构算法从斜率到Zernike系数波前重构是Shack-Hartmann传感器的核心算法。微透镜阵列下的每个光斑其质心相对于参考位置的偏移量正比于该子孔径内的平均波前斜率即dx f_MLA * (∂W/∂x)dy f_MLA * (∂W/∂y)其中f_MLA是微透镜焦距W是波前相位。有了所有子孔径位置的x/y方向斜率下一步就是重建整个波前。两种常用方法区域法zonal直接在网格上积分斜率得到相位模式法modal把波前展开成Zernike多项式的线性组合通过最小二乘拟合求解系数。工程应用里模式法更常见因为得到的Zernike系数可以直接用于描述像差而且对噪声的鲁棒性更好。MATLAB中模式法重构的关键是构建斜率与Zernike系数之间的线性关系矩阵。每个Zernike项在子孔径位置处的偏导数可以解析求出然后把这些偏导数值组合成梯度矩阵Z_grad质心偏移向量b与Zernike系数a的关系就是b Z_grad * a用最小二乘解a Z_grad \ b即可。需要注意Zernike多项式的归一化方式要和Zemax里一致标准Zernike或Fringe Zernike否则重构出的系数无法直接对比。我第一次做的时候没注意这个Zemax里用的是Fringe ZernikeMATLAB里用的是Noll归一化结果系数差了十几倍排查了很久才发现是归一化的问题。下面的示例代码展示了对某组质心偏移数据做Zernike拟合的基本流程% 假设已知子孔径网格坐标和质心偏移dx, dy % Zernike梯度矩阵构建略核心是求解线性方程 numZernike 10; Z_grad buildZernikeGradientMatrix(subapX, subapY, numZernike); b [dx(:); dy(:)]; a Z_grad \ b; % 最小二乘求解Zernike系数 % 重构波前 W_recon reconstructWavefront(a, gridX, gridY);最小二乘求解时建议先对Z_grad做奇异值分解检查一下矩阵条件数。子孔径数量少于Zernike项数时矩阵是欠定的需要截断或正则化否则拟合出的波前会剧烈振荡。3.4 Sensor融合模拟与系统级性能评估在MATLAB中做Sensor融合模拟是指把光学仿真结果与Sensor成像链路的非理想因素放在一起评估整个系统的性能。对光场相机来说关注的指标包括重聚焦图像的信噪比SNR、光学串扰的影响、微透镜间漏光导致的对比度下降对波前传感器来说关注的指标主要是质心定位误差、波前重构误差RMS、可测动态范围。一个常用的评估手段是蒙特卡洛仿真随机生成大量不同强度、不同形状的入射波前经过Zemax仿真得到光斑图在MATLAB中加上Sensor噪声、做质心提取和波前重构统计重构误差分布。这样可以得到系统在不同光照条件、不同噪声水平下的性能曲线为硬件参数选择提供依据。比如我发现当Sensor读出噪声超过30个电子时波前重构误差会快速上升尤其在弱光下质心偏移量只有0.1像素量级时噪声影响几乎不可忽略。关于Sensor融合还有一项实用技巧是在MATLAB中建立Sensor模型时把CMOS的滚动快门、暗电流分布、像素响应非均匀性PRNU都做成参数可控的模块。这样后期如果要换一款Sensor只需要修改参数配置文件不需要改算法代码。我在自己的项目里就是这种结构测试不同Sensor时非常省事。4. Zemax与MATLAB联动实操数据流与控制流4.1 文本与图像数据交互的标准流程最稳妥的离线交互方式是Zemax导出标准数据文件MATLAB批量读取。以探测面辐照度图为例Zemax里打开探测面查看器后可以右键保存数据或者在“Analysis”选项卡下的“Detector Viewer”中启用“Export Data”。建议导出为CSV或TXT格式包含坐标与辐照度值优点是可在MATLAB中用readmatrix直接读取无需额外解析。这里有一个容易踩的坑Zemax导出的辐照度单位有“W/cm^2”或“W/m^2”等选项对不同单位解析出来的数值范围差异很大。处理时最好统一转换为相对值或总能量归一化再进入MATLAB算法流程。另外CSV文件通常带有表头和数据说明用readmatrix时注意设置NumHeaderLines参数。图像数据交互方面把Zemax的辐照度图导出为高精度无损格式如TIFF再在MATLAB中读取也能保持定量信息。但要注意Zemax的显示图像默认会做“伪彩色映射”如果直接右键保存的是显示图像而不是原始数据数值精度会受很大影响。我的习惯是永远优先导出原始数据而不是截图保存除非只是做快速预览。4.2 通过ZOS-API实现参数批量扫描和自动化优化当需要批量改变微透镜阵列参数如焦距、口径、阵列间距来观察系统性能变化时手动在Zemax里一个个改参数再导出结果效率非常低。这时候用ZOS-APIZemax OpticStudio API就很有必要。ZOS-API支持Python和MATLAB两种语言接口可以直接在MATLAB中启动Zemax、打开设计文件、修改参数、运行分析并获取结果。在我常用的一套代码框架里先在MATLAB中连接Zemax% 启动Zemax COM接口Windows环境 z actxserver(ZOSAPI.Zemax); z.CreateNewApplication(); % 打开设计文件 z.LoadFile(LightFieldCamera.zmx); % 获取系统编辑器接口 TheSystem z.TheSystem; % 修改微透镜阵列焦距假设表面序号为15 surface TheSystem.LDE.GetSurfaceAt(15); surface.Radius 0.5; % 修改曲率半径 % 运行非序列追迹并获取探测面数据 TheSystem.Tools.OpenNonSequentialComponent(); % 执行Zemax的优化函数或者执行分析用API的好处不仅是可以批量修改参数还可以实现闭环优化MATLAB中定义系统评价函数例如光斑质心偏移误差或重聚焦图像对比度然后通过API自动改参数用优化算法寻找最优解。这比Zemax内置优化器更灵活尤其适合对“光学算法”联合优化的场景。例如要想在保证波前重构精度的同时最大化动态范围可以同时扫描微透镜焦距和Sensor增益两个维度的参数组合这个用Zemax本地工具做起来很麻烦但API很容易搞定。使用中有一点要当心ZOS-API版本要与Zemax版本严格匹配。每次升级Zemax都要同步检查MATLAB端是否能正常连接我遇到过API接口函数名在版本更新后变化、导致脚本报错的情况。另外ZOS-API在非序列模式下的执行速度比序列模式慢不少如果微透镜阵列单元数量上千单次追迹时间可能几十秒甚至更长。批量扫描时要估算好总时长必要时先跑小规模验证再放大到完整阵列。4.3 自定义DLL扩展Zemax功能的思路热词里频繁出现“Zemax用户自定义DLL”这在高阶应用中确实很实用。Zemax允许用户通过自定义DLL来定义非序列物体的表面形状、散射特性、材料折射率分布等。如果微透镜阵列不是标准的球面透镜而是自由曲面微透镜、双胶合结构或渐变折射率透镜可以用C/C编写DLL在Zemax中作为“User Defined”表面或物体加载。以我做过的一个变曲率微透镜阵列为例子每个微透镜的曲率半径按中心向边缘规律变化用来校正场曲。Zemax内置对象库里没有这种渐变阵列用标准微透镜阵列建模根本无法实现。我用C实现了一个用户自定义物体遍历每个微透镜单元时根据坐标计算曲率半径并输出面型编译成DLL后在Zemax的“Object Type”里选择User Defined就能和其他光学元件一样参与光线追迹了。实现过程要特别注意面型函数的偏导数计算是否正确因为Zemax追迹光线需要计算交点处的法向量如果偏导数有误追迹结果会明显异常甚至报错。当然自定义DLL的开发调试周期较长如果不是必需不建议第一版仿真就上这个方案。先看看Zemax自带模型是否够用不够再扩展。对于微透镜阵列的光场相机和波前传感器绝大多数设计场景用Zemax自带的Array对象或Non-Sequential模式完全可以解决DLL一般用于特殊面型或新材料研究。5. 常见问题与排查技巧实录5.1 高频问题速查表我把这几年做微透镜阵列仿真联调时碰到的高频问题整理成了一张表每一条都是真实踩坑换来的经验现象可能原因排查方法光斑图有明显条纹混叠微透镜周期与Sensor像素周期不匹配或离焦量错误检查D与p的比值是否为整数微透镜阵列到Sensor距离是否等于f_MLA质心偏移方向整体颠倒Zemax数据坐标系与MATLAB索引方向不一致先画质心偏移矢量图对比方向必要时翻转Y轴波前重构误差RMS很大Zernike归一化方式不一致确认Zemax与MATLAB用同一套Zernike定义重聚焦图像模糊微透镜中心与像素网格未校准用均匀白光采集图检测微透镜光斑中心建立网格映射仿真结果与实验差异大Sensor噪声与像素积分效应未建模加入泊松噪声、读出噪声、像素面积积分ZOS-API调用失败版本不匹配或应用未初始化检查Zemax版本与API版本确保OpticStudio已启动并加载设计文件非序列追迹速度极慢阵列单元数过多或光线数设置过高先减少微透镜数量做验证逐步增加合理设置光线数与探测分辨率黑盒文件无法在某些功能中分析黑盒本身限制导出前确认所需功能是否支持黑盒调用必要时另存普通版用于内部验证5.2 质心提取精度提升与亚像素处理技巧质心计算看似简单但要做到亚像素精度有几个细节必须处理好。一是窗口大小计算质心时不能把整个子孔径图像都纳入积分范围否则背景噪声像元会把质心往中心拉产生系统误差。我一般选择以最大亮度像素为中心的5×5或7×7窗口做加权质心窗口大小根据光斑尺寸调整。二是阈值处理在计算前先减去背景电平把低于一定阈值的像素置为零这样可以抑制暗电流和读出噪声对质心的干扰。三是插值质心当光斑形状不是理想高斯时可以用高斯曲面拟合或抛物线插值来提升精度比普通质心算法更稳。对于波前重构这种需要极高精度的应用建议用“加权质心 迭代优化”的方案先用质心法得到一个粗略位置然后在该位置附近做最小二乘高斯拟合以拟合中心作为最终质心坐标。这种方案在信噪比低时依然能保持在0.01像素量级的定位精度。我在MATLAB里实现时发现lsqcurvefit虽然精确但偏慢批量处理几千个子孔径时会耗时很久后来改用解析高斯拟合先取对数再二次多项式拟合速度快很多精度几乎不变。5.3 光场相机与波前传感器联调时的常见坑把光场相机和波前传感器放在同一个框架下研究时很容易混淆两者的参数约束。光场相机要求微透镜阵列位于一次像面处传感器位于微透镜焦距处波前传感器则没有“一次像面”的概念它只需要微透镜阵列分割入瞳波前Sensor同样放在微透镜焦距处。如果误把光场相机的微透镜阵列设计思路套到波前传感器上或者反过来就会导致系统性能完全偏离预期。另一个容易忽略的问题是微透镜阵列的填充因子和盲区。实际微透镜阵列存在死区微透镜间隙这些区域的光线无法被有效聚焦到Sensor上会造成光能损耗和串扰。Zemax建模时可以设置阵列的填充率MATLAB算法处理时也要考虑盲区导致的像素失效。如果不处理盲区光场重聚焦图像会出现周期性的暗网格对波前传感器来说死区附近的光斑会变形影响质心提取。仿真时我建议把填充率作为一个可调参数研究其对最终性能的影响。有一回我在项目中测试填充率从90%降到80%重聚焦图像对比度下降了将近15%这个数字足够说明盲区不是可以忽略的细节。6. 实操案例一个完整的微透镜阵列波前传感系统仿真6.1 案例指标与设计参数推导为了把前面的内容串起来我在这里跑一个完整的小案例在Zemax里设计一个Shack-Hartmann波前传感器然后在MATLAB里完成波前重构验证重构精度。假设设计指标是入瞳直径8mm微透镜阵列10×10个子孔径每个子孔径口径0.8mm波长632.8nmSensor像素尺寸10μm单个子孔径光斑覆盖约3×3像素。根据这些参数微透镜阵列的焦距需要满足光斑尺寸要求。艾里斑直径约为2.44λF其中F f_MLA / D_sub。要让艾里斑覆盖约3个像素即30μm可以算出f_MLA ≈ 8mm左右。再检查动态范围波前斜率带来的光斑偏移量不应超过子孔径半宽的一半否则光斑会跑到相邻子孔径区域设定最大偏移4个像素即40μm对应的最大波前斜率约为5mrad基本符合常见自适应光学系统的需求。在Zemax里用Zernike Fringe Phase面输入一组已知的像差系数比如离焦0.5μm、球差0.2μm在MLA平面放置10×10的微透镜阵列Sensor面放在微透镜焦距处进行非序列追迹后得到光斑阵列图。将此光斑图导出为CSV文件。6.2 MATLAB波前重构与误差评估在MATLAB中我按下面几步处理读取光斑图像按子孔径划分区域对每个子孔径在3×3像素邻域内做加权质心提取减去参考位置理想平面波时光斑位置得到每个子孔径的斜率用Zernike模式法重构波前得到Zernike系数与Zemax输入的已知Zernike系数对比计算RMS误差。实际处理后若Sensor噪声较低光子总数10万个以上重构波前RMS误差可以做到1%以内。但随着噪声增大或光斑亮度降低误差会快速上升。这个仿真结果也提醒我们在实际硬件系统中为了保证波前测量精度必须确保每个子孔径的光斑信噪比足够高必要时需要增加曝光时间或提高照明光功率。6.3 参数灵敏度分析与设计改进方向在这个案例基础上我做了几组灵敏度分析发现对波前重构精度影响最大的参数依次是微透镜焦距精度、Sensor像素尺寸一致性、光斑提取窗口大小。微透镜焦距如果偏差1%重构波前RMS误差大约增加1.5%Sensor像素尺寸如果有2%的随机误差质心提取会产生明显的畸变。所以对精密波前传感器而言微透镜阵列制造公差和Sensor像素一致性是决定系统精度的关键这往往比算法选择更重要。改进方向主要有两点一是采用更长焦距的微透镜阵列用光斑偏移量放大波前斜率信号代价是缩小可测动态范围二是在算法端引入参考标定数据在系统搭建后用已知平面波标定每个子孔径的参考质心位置可以在一定程度上消除固定模式误差和安装误差。7. 几个值得记住的实操习惯做这类ZemaxMATLAB联调项目有几个习惯是我个人从一次次返工中总结出来的写在这里给后来人参考。第一从第一天开始就建立数据规范。Zemax导出的文件命名、格式、单位都要统一否则到后期几十个文件混在一起根本分不清哪个对应哪组参数。我一般用“日期_版本_参数名_参数值”的命名格式同时在导出文件里保留备注信息。第二在MATLAB代码里参数不要写死。微透镜周期、焦距、像素尺寸、噪声水平这些都要做成变量最好放在一个配置文件或结构体里方便批量修改和参数扫描。这看起来是常识但很多人为了赶进度直接硬编码后面改参数时痛苦万分。第三不要迷信仿真结果。Zemax和MATLAB仿真是对物理系统的近似微透镜阵列的真实制造误差、Sensor的不均匀性、装配公差等很难完全反映在模型里。仿真结果能用来验证算法、选择方案但最终还是要到实验平台上验证。条件允许的话在设计初期就给实验留好后路比如微透镜阵列和Sensor之间的距离最好设计成可调方便装配时校准。第四善用版本控制和备份。Zemax设计文件、MATLAB脚本、导出的数据文件建议全部纳入版本管理。我遇到过因为误改了Zemax参数导致整组仿真数据无法复现的情况没有备份只能全部重跑损失了整整两天时间。这篇文章从微透镜阵列的核心设计逻辑到Zemax建模到MATLAB算法实现再到双平台联动和坑点排查算是把我这几年的经验都梳理了一遍。如果你正在做光场相机或波前传感器的仿真课题建议先照着上面的流程跑通一个小规模的案例把数据链路的每一环都搞清楚再放大到完整系统。最后再分享一个小技巧在Zemax里设置微透镜阵列时别急着上高精度非序列追迹先用近轴近似和解析公式估算一下光斑尺寸、采样关系对不对确认整体布局没有方向性错误后再做精细仿真能省下大把时间。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门