多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

基于SLM的高斯光束转平顶光束:GS算法与直接计算相位方法(MATLAB实现)

基于SLM的高斯光束转平顶光束:GS算法与直接计算相位方法(MATLAB实现) 做SLM光束整形的同事大多有这个体验激光器出来的光斑能量分布是高斯型中间亮、边缘弱看着精致但在很多场景里不实用。无论是激光加工、光刻还是荧光显微照明往往需要一种能量分布均匀的“平顶光束”。如果手头有一台空间光调制器SLM最直接的想法就是往上面加载一块相位图把入射的高斯光束变成目标平顶。这件事在MATLAB里怎么做核心是两条路一是用GS算法迭代求解SLM相位分布二是不走迭代、直接算出相位图。本文就把这两条路线完整梳理一遍并附上可以直接运行的MATLAB代码和调试心得适合正在做光场调控、光束整形相关课题的本科生、研究生以及刚接触SLM的工程师参考。1. 为什么要把高斯光束变成平顶光束以及SLM方案的优势1.1 高斯光斑在均匀照明场景里的短板高斯光束最大的特征是强度从中心向外呈高斯型衰减中心亮、边缘暗。单模激光器输出基本都是这种分布在需要聚焦、耦合光纤、做光学捕获时这反而是优点因为能量集中在中心衍射极限也好。可是一旦遇上“大面积均匀照明”高斯分布的短板立刻暴露样品中心被照得发亮边缘却明显偏暗这会导致加工不均匀、光刻线宽不一致、荧光图像背景不平坦等一连串问题。平顶光束就是来解决这个问题的。它的强度分布在目标区域内尽量保持恒定只在边缘附近陡峭下降像“帽子”一样平整。激光退火、晶圆划片、激光熔覆、光动力治疗、显微照明等领域对这类分布的需求非常迫切。更关键的是很多时候是在已有激光器的前提下改造光斑而不是重新采购一套光源这就需要一个灵活的波前整形方案。1.2 主流方案对比微透镜阵列、非球面、DOE与SLM把高斯光变成平顶光的器件方案并不少我列个表说明各自的特点方便按需求选择方案原理优点缺点典型场景微透镜阵列把光束分成多个子光束再叠加对输入光斑位置不太敏感均匀化效果好结构固定只能做特定尺寸平顶调节困难照明系统、激光匀化非球面透镜组通过透镜面形重新分配能量效率高、设计简单一个透镜组对应一个固定目标打样贵装调敏感大批量固定整形衍射光学元件(DOE)刻蚀固定微结构相位效率高设计自由度大一旦加工不可更改周期长工业量产整形空间光调制器(SLM)实时加载可编程相位分布灵活换目标只需换相位图有像素化、量化误差和响应延迟研发验证、动态整形从这张表能看出来SLM的核心优势是“可编程”。同一套光路里今天做平顶、明天做涡旋、后天做贝塞尔只需要在电脑上换一张相位图。对于还在摸索阶段的项目这个灵活性远比最终效率重要。这也是为什么我下面的内容全部围绕SLM展开你最终要知道的就是那张加载到SLM上的相位分布怎么算。1.3 本文两条技术路线的适用判断GS算法和直接计算并不是互斥的它们各有适应面GS算法是相位恢复领域的经典迭代方法。它通过交替施加“入射面幅度约束”和“目标面幅度约束”逐步逼近一个能实现目标光强分布的相位解。优点是适应性强高斯转任意形状平顶、环形、多焦点阵列都能做。缺点是迭代耗时而且可能陷入局部最优。直接计算则是用几何光学映射或傅里叶逆变换一步给出相位图。计算快但精度通常不如迭代后的结果更适合要求不高或者需要实时更新的场景。更实用的做法是两者结合先用直接计算得到一个合理的初始相位再用GS迭代精修。下面我会把这个组合流程完整讲清楚。2. GS算法的迭代逻辑与MATLAB参数设计2.1 透镜焦面上的夫琅禾费衍射就是一次傅里叶变换GS算法能用在SLM光束整形上底层依赖一个非常关键的光学关系当一个复振幅场经过薄透镜后在透镜后焦面上得到的是该场的傅里叶变换。这个结论在实验室里表现为SLM出射的场 ( U_{\text{in}}(x, y) )经过焦距为 ( f ) 的透镜在后焦面上得到 ( U_{\text{out}}(u, v) )两者满足[ U_{\text{out}}(u, v) C \cdot \mathcal{F}{U_{\text{in}}(x, y)} ]其中 ( C ) 是常数因子空间频率坐标与焦面物理坐标的关系是 ( u x_f / (\lambda f) )。这个性质把复杂的衍射传播问题化简成了MATLAB里的fft2和ifft2这是整个仿真能跑起来的前提。具体到数值仿真要注意一个容易坑人的细节fft2输出的第一个点对应的是零频而不是阵列中心。因此做正向传播时要用fftshift(fft2(ifftshift(Uin)))反向传播时用ifftshift(ifft2(fftshift(Uout)))。这是一套标准的坐标对齐操作少了ifftshift或者多了一次fftshift结果相位就会乱掉。2.2 GS算法四步循环的物理含义GS算法解决的是这样一个逆问题已知入射面的振幅分布 ( A_{\text{in}} )也已知目标面的振幅分布 ( A_{\text{target}} )要求求出入射面的相位分布 ( \phi(x, y) )使得正向传播后焦面的振幅尽量接近 ( A_{\text{target}} )。迭代过程分四步和光学系统中的前向与反向传播严格对应正向传播将入射面复场 ( A_{\text{in}} \cdot e^{i\phi} ) 做傅里叶变换得到焦面复场 ( U_f )。施加目标面约束保留 ( U_f ) 的相位把振幅替换为目标振幅 ( A_{\text{target}} )得到修正后的焦面场。反向传播将修正后的焦面场做傅里叶逆变换回到入射面得到复场 ( u_{\text{back}} )。施加入射面约束保留 ( u_{\text{back}} ) 的相位把振幅替换为入射高斯振幅 ( A_{\text{in}} )得到新的入射面复场提取相位 ( \phi ) 进入下一轮。这个循环的物理意义很直白每次前向传播都会偏离目标我们就强行把振幅“掰”回目标值每次反向传播同样把振幅“掰”回入射高斯值。经过几十轮交替投影相位分布会收敛到一个同时近似满足两个约束的解。需要说明的是GS不能保证完全收敛到全局最优尤其目标分布很尖锐时容易出现局部振荡。但工程上通过合理选参、加权、过采样等技巧完全能把误差压到可用范围。后面第六章我会专门讲这些坑。2.3 仿真关键参数的设计做仿真前先把参数定清楚这一步比写代码本身更重要。我的建议参数如下参数符号推荐值说明波长(\lambda)532 nm常见可见光波段采样点数N512二维矩阵大小需兼容FFTSLM像素间距(d_x)15 μm常见LCoS型SLM参数透镜焦距f300 mm决定焦面坐标尺度入射高斯束腰(w_0)2 mm取SLM有效口径的1/3到1/2目标平顶半径R3 mm需和高斯能量分布匹配目标超高斯阶数n8~16阶数越高边缘越陡但振荡也越强这几个数值要满足一个隐含条件焦面采样间距。焦面相邻采样点的物理间距为[ \Delta x_f \frac{\lambda f}{N \cdot d_x} ]代入上面的值[ \Delta x_f \frac{532 \times 10^{-9} \times 0.3}{512 \times 15 \times 10^{-6}} \approx 2.08 \text{ cm} ]这个值决定了焦面上每个“像素”代表的物理尺寸设计目标平顶半径时要用它换算。如果觉得焦面坐标太稀疏可以减小焦距或增大采样点数。3. MATLAB实现GS算法的完整过程与结果评估3.1 坐标网格搭建与频域间距计算先把仿真坐标系搭起来。核心是生成入射面坐标网格和焦面坐标网格并保证两个网格的取样满足傅里叶变换关系。%% 参数定义 lambda 532e-9; % 波长 532 nm N 512; % 采样点数 dx 15e-6; % SLM像素间距 15 um f 0.3; % 透镜焦距 300 mm %% 入射面坐标网格 x (-N/2 : N/2-1) * dx; [X, Y] meshgrid(x, x); r sqrt(X.^2 Y.^2); %% 焦面坐标网格 df lambda * f / (N * dx); fx (-N/2 : N/2-1) * df; [FX, FY] meshgrid(fx, fx); rho sqrt(FX.^2 FY.^2);这里df就是焦面采样间距对应我前面算的约2.08 cm。rho是焦面每个采样点到中心的距离供目标平顶分布使用。3.2 入射高斯场和目标平顶场的构造入射场是束腰为 ( w_0 ) 的高斯振幅分布。在准直条件下可以认为SLM入射波前近似平面因此只写振幅、不写初始相位%% 入射高斯振幅场 w0 2e-3; A_in exp(-(r/w0).^2); % 振幅分布 %% 目标平顶振幅场超高斯分布 R 3e-3; n 12; A_target exp(-(rho/R).^n);高斯振幅场写成exp(-(r/w0).^2)对应强度分布 ( \exp(-2r^2/w_0^2) )这是高斯光束常用的振幅表达。目标平顶用超高斯函数表示阶数 ( n ) 控制边缘陡峭度阶数越高边缘越陡越接近理想平顶但阶数太高会引入强烈的边沿振荡。我一般从 ( n12 ) 起步性能不满意再微调。3.3 GS主循环代码下面是GS算法的核心迭代代码。初始相位我同时写了两种选择全零相位和直接计算相位直接法在第四章讲读者可以自行切换测试。%% 初始相位 phi rand(N) * 2 * pi; % 随机初始相位或者用 zeros(N) 或直接计算相位 %% GS迭代 numIter 200; for k 1:numIter % 正向传播 Uin A_in .* exp(1i * phi); Uf fftshift(fft2(ifftshift(Uin))); % 目标面约束替换振幅为 A_target保留相位 Uf_modified A_target .* exp(1i * angle(Uf)); % 反向传播 Uback ifftshift(ifft2(fftshift(Uf_modified))); % 入射面约束替换振幅为 A_in保留相位 phi angle(Uback); % 每20轮输出一次误差 if mod(k, 20) 0 intensity abs(Uf).^2; intensity_norm intensity / max(intensity(:)); target_intensity A_target.^2; target_norm target_intensity / max(target_intensity(:)); err sqrt(mean((intensity_norm - target_norm).^2, all)); fprintf(Iteration %d, RMS error %.4f\n, k, err); end end这段代码最核心的部分就是四个操作fft2前向传播、目标振幅替换、ifft2反向传播、入射振幅替换。多说一句有些教材在正向传播时不显式替换输入振幅而是在每次迭代开头直接乘A_in这样其实是一样的入射面约束已经通过乘法实现了。3.4 输出质量评估误差、效率与剖面迭代结束后不要直接拿相位图去实验先在仿真里看三个指标第一是RMS误差。上面代码里已经计算了归一化强度分布与目标强度分布的均方根误差。这个指标反映整体相似度一般在0.01到0.05之间属于可接受。第二是衍射效率。SLM整形本质上是用干涉把能量重新分配不可能做到入射能量全部进入目标区域。效率定义为目标区域内的能量除以入射面总能量mask (rho R); efficiency sum(sum(abs(Uf).^2 .* mask)) / sum(sum(abs(Uin).^2));我做过的大量仿真里高斯转平顶的效率通常在70%~85%之间。如果发现效率特别低多半是目标平顶半径相对高斯束腰取得过大能量浪费在边缘。第三是剖面曲线。把输出强度沿径向画一条剖面能直观看出平顶的均匀度、边缘陡峭度和是否有中心凹陷profile_in sum(abs(Uf).^2, 1); % 沿x轴统计plot(linspace(-max(fx), max(fx), N), profile_in / max(profile_in));剖面应该在中部接近水平线边缘快速下降。如果中心出现明显凹坑第六章会给出原因和解决办法。 ### 3.5 用直接计算相位做初值大幅提升收敛速度 我实际测试下来全随机初始相位虽然也能收敛但需要比较多的迭代轮数而且结果波动大。更好的做法是先用第四章介绍的几何映射法直接算一个相位作为初值再交给GS迭代精修。这样通常20~50轮就能达到随机相位200轮的效果。 具体来说在GS主循环前加一行 matlab phi phi_map; % 几何映射法得到的相位然后只迭代80轮左右。结果往往比纯GS更稳定这个技巧我建议直接纳入日常工作流。4. 不迭代直接计算SLM相位分布的两条路线标题里提到“直接计算SLM相位分布”这一节详细展开两种不依赖迭代的算法。它们不能完全替代GS但作为初值或者快速方案非常有用。4.1 傅里叶逆变换法最简单的“一步相位”这个方法在概念上一句话就能说清目标是一个平顶振幅分布给目标面随便指定一个相位分布然后对整个复场做一次傅里叶逆变换再把入射面场的相位取出来。%% 傅里叶逆变换法目标相位设为0 U_target A_target; % 目标振幅相位为0 u_in ifftshift(ifft2(fftshift(U_target))); % 逆传播到入射面 phi_direct_ift angle(u_in);为什么这样可行因为傅里叶逆变换会把焦面上的平顶振幅分布映射回入射面入射面复场的相位理论上包含了产生该目标分布所需的波前信息。但问题在于入射面的实际振幅是高斯的而不是逆变换得到的那个振幅。直接用相位配合高斯振幅再正向传播目标分布就会有偏离。这个“一步相位”误差有多大取决于该解复场振幅与高斯振幅的接近程度。在目标尺寸与高斯匹配较好的情况下均匀度还能看不匹配时效果就很差了。所以我的结论是它适合拿来快速预览或者当GS初始值不建议直接用于实验。4.2 几何映射法由能量守恒推导坐标映射几何映射法是从能量守恒出发推导坐标变换关系思路更偏物理。假设入射高斯强度分布归一化为[ I_{\text{in}}(r) \exp\left(-\frac{2r^2}{w_0^2}\right) ]强度在半径 ( r ) 内的能量占比为[ P_{\text{in}}(r) 1 - \exp\left(-\frac{2r^2}{w_0^2}\right) ]目标是一个半径为 ( R ) 的均匀圆平顶半径 ( \rho ) 内的能量占比为[ P_{\text{out}}(\rho) \frac{\rho^2}{R^2} ]能量守恒要求两式相等所以[ \frac{\rho^2}{R^2} 1 - \exp\left(-\frac{2r^2}{w_0^2}\right) ]解出映射关系[ \rho(r) R \sqrt{1 - \exp\left(-\frac{2r^2}{w_0^2}\right)} ]这个式子很漂亮高斯中心能量集中所以 ( \rho ) 在中心增长快高斯基底能量稀薄所以 ( \rho ) 在外围趋于饱和。有了坐标映射相位可以借助稳相近似得到。在傍轴条件下产生该映射所需的SLM相位近似为[ \phi_{\text{map}}(r) \frac{\pi}{\lambda f} \left[ \rho^2(r) - r^2 \right] ]不同文献的符号约定可能略有差异实际使用前先在仿真中正向传播验证一次如果出现目标分布反转之类的情况调整符号即可。MATLAB实现非常简短%% 几何映射法相位 rho_map R * sqrt(1 - exp(-2 * (r / w0).^2)); phi_map pi / (lambda * f) * (rho_map.^2 - r.^2); phi_map mod(phi_map, 2*pi);这里mod(phi_map, 2*pi)把相位折叠到0~2π范围方便后续输出灰度图。需要提醒的是几何映射法在推导时默认了目标平顶边界与高斯边界匹配。如果目标半径 ( R ) 设置得远大于高斯束腰能提供的有效区域映射到外圈的相位会对能量扩散产生极大梯度实际整形质量会下降。实用经验是让 ( R ) 控制在 ( 0.5w_0 ) 到 ( 1.2w_0 ) 范围内再结合GS精修。4.3 三种方法的实测对比我做了一个标准测试同一组参数分别用纯GS、几何映射法、傅里叶逆变换法求相位再统一正向传播评估。结果很有代表性方法计算耗时均匀度边缘陡峭度相位连续性是否适合直接实验傅里叶逆变换法极快较差一般随机跳变否几何映射法极快中等中等光滑连续可作初值纯GS迭代较慢好好较连续是几何映射GS精修中等最好最好较连续强烈推荐从这张表能看出组合方案是性价比最高的路线。我后来的项目基本都是“几何映射打底、GS精修收尾”既保证了收敛速度又拿到了最好的平顶质量。5. 从相位分布到SLM硬件加载的落地细节5.1 相位图转8位灰度图SLM的相位调制是通过加载灰度图实现的常见的LCoS型SLM为8位灰度256个等级。相位范围0~2π对应灰度0~255%% 相位图转灰度图 phi_final mod(phi, 2*pi); gray round(phi_final / (2*pi) * 255); imwrite(gray, slm_phase.png);加载到SLM时灰度0对应相位0灰度255对应相位接近2π。需要注意不同厂商的SLM在相位-灰度关系上可能有差异有些甚至有非线性响应实验前最好用标准干涉法做一个校准否则实验和仿真会有一个系统偏差。保存灰度图时建议用PNG格式避免JPG压缩带来的灰度噪声。同时把未折叠的相位矩阵.mat也存一份方便后续复用或者做量化分析。5.2 量化误差、像素化效应与零级光8位量化本身给相位引入了误差最大量化误差约为 ( \pi/128 \approx 0.0245 ) rad。对于远场强度分布这个误差对均匀度的影响通常不大但在相位跳变剧烈的区域可能造成一些暗点。想验证量化影响可以在仿真中模拟%% 模拟8位量化 phi_quantized round(phi_final / (2*pi) * 255) / 255 * 2*pi;把量化后的相位重新代入正向传播比较输出光场与原始相位的结果。如果差异明显说明相位分布里存在很多高频细节这时候可以通过降低目标超高斯阶数、或者给相位加平滑处理来缓解。SLM另一个固有问题是像素间隙。液晶像素之间存在不透光的死区填充因子一般在93%~96%之间。死区不参与相位调制会产生零级背景光底叠加在目标光斑中形成杂散光。这个没法完全消除只能通过光路设计来减轻。5.3 叠加闪耀光栅把有用级次分离出来实验中经常遇到零级光与目标光叠在一起的问题一个通用解法是给相位图叠加一个闪耀光栅blazed grating。光栅会让衍射光在空间上偏移一个角度把高效的一级衍射和其他级次分开再用光阑选择你需要的那一级。%% 叠加闪耀光栅周期10个像素 period_pixel 10; grating 2*pi * mod(X / dx, period_pixel) / period_pixel; phi_total mod(phi_final grating, 2*pi); gray round(phi_total / (2*pi) * 255);光栅周期越短偏移角越大但像素量化导致的二级衍射噪声也会变强。10个像素周期是一个比较平衡的选择。需要说明的是叠加光栅后衍射效率会略有下降不过换来了更干净的信号背景在实验上通常是值得的。5.4 SLM校准与偏振注意液晶型SLM对入射偏振非常敏感。常见LCoS-SLM要求线偏振光入射且偏振方向需要与液晶分子取向对齐否则相位调制效率和调制范围都会大幅下降。实验前务必确认入射光是经过半波片或偏振片调整后的线偏振光。此外SLM的相位-灰度响应曲线是波长相关的。如果你换了激光器波长之前标定的灰度-相位对应关系可能失效需要重新标定。最直接的验证方法是用干涉仪看单点相位随灰度的变化或者直接在焦面观察已知透镜相位的聚焦位置。6. 实战中常见的坑与平顶质量提升技巧6.1 相位初值选择与GS不收敛GS算法最迷惑人的一点是有时迭代了200轮误差还是不下来输出分布和目标的差距始终很大。我遇到这种情况时第一反应一般是检查初始相位和参数匹配。纯随机初始相位在目标约束较严苛时容易陷入局部极小。换成几何映射相位做初值多数情况下能绕过这个问题。另外如果目标平顶半径太大超出了高斯能量的有效覆盖范围任何算法都很难同时保证效率和均匀度这时要缩小 ( R ) 或者改用更柔和的边缘目标。还有一个容易被忽略的因素是超高斯阶数 ( n )。如果你的目标阶数设为50边缘几乎是垂直的GS会在边界处反复振荡。把阶数降到8~16让边缘有一个平滑过渡迭代稳定性和最终均匀度都会提升。6.2 中心暗斑目标相位不能瞎给有一段时间我的输出平顶中心总是有一个暗点百思不得其解。最后定位到问题出在GS的目标面约束里如果目标振幅分布是实数比如A_target本身是实函数而目标面相位一直是零相当于强行约束了目标面的相位关系。这种额外约束会给迭代徒增负担还容易在中心产生相位奇点形成暗斑。解决方法是给目标分布加一个缓变的二次相位相当于在焦面附近引入一个离焦量让GS有更多的自由度去匹配振幅约束。常用的做法是%% 给目标加二次相位q为离焦系数 q 30; U_target A_target .* exp(1i * q * (rho/max(rho(:))).^2);在迭代中每次对修正后的焦面场取相位约束时都用U_target的相位保留下来而振幅始终保持A_target。加上这个可调相位后中心暗斑问题通常能明显改善。这个技巧知道的人不多但在实际项目中非常管用。6.3 超高斯阶数与吉布斯振荡的平衡平顶边缘越陡均匀度越好但傅里叶光学里的吉布斯效应也越明显——目标边缘附近会出现过冲和振荡条纹。这是由衍射本质决定的不会因为算法改进而完全消失只能通过设计目标来缓解。我常用的做法是优先保证中央区域的均匀度牺牲一点边缘陡峭度。具体就是在超高斯阶数上做文章阶数12左右是很多应用的甜点区。如果应用中边缘必须陡峭比如光刻那就要接受边缘振荡并在实际使用中利用光阑只取中央平坦区。6.4 加权GS算法(WGS)的改进思路标准GS对所有像素一视同仁地施加振幅约束这其实是不必要的。目标区域内的强度要严格匹配但目标区域外可以宽松一些。加权GS就是利用这一点把迭代自由度释放给区域外让能量集中更高效。加权GS的核心改动在目标面约束这一步。标准做法是[ U_{\text{mod}} A_{\text{target}} \cdot e^{i\arg(U_f)} ]加权之后改为[ U_{\text{mod}} \left[ W \cdot A_{\text{target}} (1-W) \cdot |U_f| \right] \cdot e^{i\arg(U_f)} ]其中权重因子 ( W ) 在目标区域内取1在区域外取0.1~0.3。这意味着区域外的振幅约束被放松算法能更自由地分配能量。实现起来只需在GS循环里加一个权重矩阵%% 加权GS目标区域内权重1区域外权重0.2 W zeros(N, N); W(rho R) 1; W(rho R) 0.2; % 迭代内的目标约束步骤 Uf_modified (W .* A_target (1-W) .* abs(Uf)) .* exp(1i * angle(Uf));我在实验中用加权GS处理过大尺寸平顶均匀度从标准GS的90%左右提升到接近97%效率也明显改善。这个方法强烈推荐。6.5 从仿真到实验的验证流程最后聊一下实验前的自检流程这一套是我自己磨出来的能避免大量无效的光路调试时间第一步仿真输出相位图同时保存未量化的相位矩阵和量化灰度图。第二步把相位图重新代入正向传播对比量化前后输出光场。如果量化导致明显退化回到相位设计环节进行平滑处理。第三步光路中先不加SLM用相机观察入射高斯光斑确认光轴和偏振。第四步加载相位图在透镜焦面用CCD采集光斑。如果中心出现异常亮点多半是零级光或SLM死区背景调光阑或增强闪耀光栅周期。第五步对比CCD采集的剖面和仿真剖面。如果形状大体一致但强度差很多检查SLM灰度-相位响应和偏振方向。个人体会最深的还是那句仿真里的相位分布再漂亮如果SLM校准没做好实验上也会打折扣。所以在投入时间做复杂算法之前先花半天时间把SLM的相位-灰度曲线摸清楚后面所有实验都会顺利很多。
返回列表