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

数字全息实验全流程:光路搭建、干涉记录与Python重建

简介数字全息实验通常包含全息图采集、干涉条纹解读与数值重建几个步骤这份实例演示包面向光学工程、电子信息类本科生及研究生也适合数字全息方向的科研人员作为程序编写与算法验证的参考。资源共3个文件tif格式的实验原始全息图、png格式的光路示意图以及m格式的FFT重建脚本整体压缩后仅1.79MB下载与解压都很方便。光路示意图清晰标明了物光、参考光与记录平面的位置关系可帮助使用者理解全息干涉记录的原理m脚本基于快速傅里叶变换实现从全息图到再现像的完整重构支持直接运行并可调整滤波参数观察不同重建效果对深入理解全息重建过程十分有帮助。目前已有1104人学习下载无论是用于课程实验、期末课题还是实际全息系统的结果分析都能从中获得可复用的处理路径和实验思路。1. 数字全息实验的第一步先看清记录与再现的不对等把 CCD 或 CMOS 对准一个三维物体按下快门得到的是一张没有任何立体感的二维强度图。数字全息实验做的事情是在这张强度图里藏进物体的相位信息再通过数值计算把相位“解”出来从而重建出物体的波前。很多第一次接触这个领域的人会误以为数字全息只是“拍一张带干涉条纹的照片”但真正动手做实例演示时会发现从条纹图到三维重建之间隔着三条必须跨过的坎光路调出高质量的干涉条纹、重建算法选对衍射模型、参数标定做到微米级准确。这篇文章要做的就是把这套从光路搭建、数据采集到 Python 重建的全流程讲清楚让有基本光学常识和编程能力的工程师能在自己的实验台上复现出一个可用的数字全息系统。2. 数字全息的物理模型干涉记录与数值重建为什么是两步2.1 强度图里没有相位干涉条纹是相位的编码方式数字全息实验的记录过程本质上是让物光与参考光在探测器表面叠加。假设物光复振幅为 O(x, y)参考光为 R(x, y)探测器记录到的强度分布可以写成I(x, y) |O(x, y) R(x, y)|^2 |O|^2 |R|^2 O·R* O*·R其中最后两项是干涉项包含了物光的振幅和相位信息。这里的核心物理事实是相机只能记录强度 I而 O 和 R 的相位都被“编码”在干涉条纹的对比度和位置里。号频项 O·R* 与共轭项 O*·R 在频域中对称分布在零频两侧只要参考光是平面波或球面波这两个项就能在空间频谱中被分离开。这引出了数字全息与普通成像的本质区别普通成像直接记录物体各点的强度数字全息记录的是物光与参考光的二维干涉图物体的三维信息经过一次光学傅里叶变换之后以条纹的形式被“冻结”在单帧图像里。实验中判断记录质量好不好看的不是图像清不清晰而是条纹对比度够不够高、条纹有没有断线、频谱能否分离。2.1.1 离轴全息与同轴全息的选型逻辑在实例演示中光路布局直接决定了后续重建算法的复杂度。同轴全息物光与参考光共轴传播记录的是 Gabor 全息图。优点是光路简单、对相干性要求低缺点是零频项与号频项重叠重建时必须用相移法或迭代法消除孪生像。离轴全息物光与参考光以一定夹角 θ 入射到探测器。这个夹角使号频项在频域中偏移到载频位置一次傅里叶变换就能提取物光场。代价是分辨率受限于载频与探测器像素尺寸的匹配关系。个人做实验演示我一般会优先选离轴全息原因很实际不需要压电陶瓷相移器单帧采集就能重建调试门槛低。而离轴全息的核心调节参数是参考光与物光的夹角这个角度决定了频谱能否分离也直接限制重建像的分辨率。2.2 数值重建的三个模型菲涅尔积分、角谱法与傅里叶变换法2.2.1 菲涅尔衍射积分适用于记录距离远大于孔径尺寸的场景菲涅尔近似是数字全息重建最常用的模型。当传播距离 z 满足菲涅尔条件时重建光场可以写成U(x_i, y_i) exp(jkz) / (jλz) · exp[jk(x_i² y_i²) / (2z)] · FFT{ I(x, y) · R*(x, y) · exp[jk(x² y²) / (2z)] }这里的核心操作是全息图先乘以参考光共轭 R* 得到物光场再乘一个二次相位因子完成菲涅尔变换最后做一次傅里叶变换。输出平面的像素尺寸是 λz / (N·Δx)这意味着重建像的分辨率会随距离 z 增加而变粗和实际物理中的衍射极限一致。2.2.2 角谱法没有最小距离限制但需要两次傅里叶变换角谱法严格求解瑞利-索末菲衍射积分不做菲涅尔近似重建公式为U(x_i, y_i) IFFT{ FFT{ I·R* } · H(fx, fy) }其中传递函数 H(fx, fy) exp[jkz·√(1 - λ²fx² - λ²fy²)]。角谱法最吸引人的特性是输出平面的像素尺寸始终等于输入平面的像素尺寸不随距离变化。这在做自动对焦扫描时非常有用——不同 z 值下重建像的尺寸保持一致可以直接比较清晰度。实际演示中我的建议是如果 z 大于 10 cm 且物体尺寸小用菲涅尔积分如果 z 在 5 cm 以内或需要等像素重建用角谱法。两者在 z 值较小、数值孔径较大时结果差异明显菲涅尔近似会引入球面相位误差。2.2.3 重建像中必然出现的三个项零频、实像与孪生像无论用哪种衍射模型对离轴全息做一次傅里叶变换后频谱里都包含三个分量分量位置物理含义零频项频谱中心物光强度与参考光强度的和不包含相位信息号频项实像偏离中心由夹角决定物光的原始波前重建后得到物体的实像共轭项孪生像与实像对称物光共轭波前重建后是散焦的虚像与实像重叠会干扰观察分离这三个项的操作叫频谱滤波对全息图做 FFT在频域中把号频项抠出来平移到频谱中心再做逆变换得到干净的物光分布。这个操作的精度直接决定了重建像的信噪比。滤波窗口太小会切掉高频细节窗口太大会混入共轭像的成分。实操中我通常用高斯窗口做软截断而不是矩形硬截断可以有效抑制振铃效应。3. 实例演示用一台 USB CMOS 搭建数字全息实验光路并完成重建3.1 光路器件的选型与参数匹配3.1.1 最小可用器件清单数字全息实验对器件的要求远低于大多数人的直觉。不需要几万块的科研相机一台工业 USB CMOS 即可满足教学级需求。关键参数是像素尺寸和分辨率而不是量子效率。器件推荐参数说明激光器632.8 nm He-Ne 或 650 nm 激光二极管相干长度要求不苛刻几厘米即可分束器非偏振分束立方体分光比 50:50比平板分束器更容易对准反射镜两个镀膜与激光波长匹配用于调节参考光路长度和入射角扩束准直系统40x 物镜 25 μm 针孔 准直透镜把激光束扩展成直径 2-3 cm 的平行光相机像素尺寸 2.2-5.5 μm分辨率 1920×1080 以上像素尺寸越小可记录的干涉条纹空间频率越高被测物体分辨率板或金属字模透射式或反射式均可优先选择高对比度物体这里必须注意一个容易埋雷的参数相机像素尺寸与干涉条纹间距的关系。干涉条纹的空间频率 f_fringe 2·sin(θ/2) / λ要让条纹被正确采样必须满足 f_fringe ≤ 1 / (2Δx)即奈奎斯特条件。以 650 nm 波长、3.45 μm 像素尺寸为例最大可记录夹角约 5.4 度。超过这个角度条纹发生混叠重建时会出现莫尔条纹。3.1.2 马赫-曾德尔光路是最适合实例演示的布局离轴数字全息实验中马赫-曾德尔干涉仪是使用频率最高的布局。它把物光和参考光分到两条独立的臂上方便分别调节光强和光程缺点是占桌面空间较大。另一种常见选择是迈克尔逊布局反射式测量时更紧凑但物光与参考光共用一部分路径调节耦合度更高。马赫-曾德尔光路的调节顺序我一般按下面步骤走先用目镜或白屏确认激光器输出已扩束准直束斑均匀无散射环。放置分束器 BS1将光束分成物光臂和参考光臂两臂光程差控制在相干长度内。在物光臂安装物体调整物体到相机的距离 z这个距离就是后续重建时的传播距离需要精确测量。调节参考光臂的反射镜 M2使参考光以约 2-3 度的夹角斜入射到相机靶面。调节 M2 时观察相机实时画面可以看到条纹从无到有、从疏到密的变化。理想状态是条纹方向一致、间距均匀、对比度高于 0.3视场内没有暗斑或断条。如果条纹弯曲说明参考光不是平面波而是球面波需要检查准直情况。3.2 采集过程的关键动作调对比度、锁定曝光、消除振动3.2.1 光强匹配是条纹对比度的决定因素条纹可见度定义为 V 2√(I_o · I_r) / (I_o I_r)当物光与参考光光强相等时取得最大值 1。实际操作中物光经过物体散射后到达相机的光强往往远弱于参考光所以需要用中性密度滤光片衰减参考光路或者调整 PBS 的分光比。调光强要在关闭环境光后进行用相机软件查看灰度直方图。我的做法是先挡住物光臂把参考光峰值灰度调到相机满量程的 70% 左右再挡住参考光臂把物光调到 30%-40%。然后两臂同时打开观察干涉条纹如果对比度不够微调 ND 滤光片的衰减倍数。3.2.2 采集程序与保存格式采集端不需要专用软件用 Python 绑定相机 SDK 就能完成。以下代码基于 OpenCV 的 VideoCapture 接口适用于绝大多数 UVC 协议的 USB 相机import cv2 import numpy as np cap cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080) cap.set(cv2.CAP_PROP_EXPOSURE, -5) # 手动曝光避免自动增益漂移 cap.set(cv2.CAP_PROP_GAIN, 0) # 固定增益为 0 # 等待相机稳定 for _ in range(30): ret, frame cap.read() ret, frame cap.read() gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 保存为 16 位无损格式保留完整动态范围 cv2.imwrite(hologram.png, gray) print(灰度范围: {} - {}.format(gray.min(), gray.max())) cap.release()这段代码的核心是关闭自动曝光和自动增益。任何一帧图像的强度波动都会直接进入重建结果表现为相位噪声。保存格式上PNG 无损压缩是首选不要用 JPEGJPEG 的块效应在高频条纹区域会产生明显的伪影。提示如果相机没有手动曝光接口可以用遮挡物光后再采集一帧暗场图在重建前对全息图做减背景处理。这个操作可以消除固定模式噪声。3.3 从全息图到重建像的核心代码采集到全息图后重建过程全部在 Python 中完成。以下代码实现离轴全息的频谱滤波和角谱法重建import numpy as np from numpy.fft import fft2, ifft2, fftshift, ifftshift def angular_spectrum_reconstruction(hologram, wavelength, z, pixel_size): 角谱法数值重建 hologram: 二维数组数字全息图 wavelength: 光波长单位米 z: 衍射传播距离单位米 pixel_size: 相机像素尺寸单位米 ny, nx hologram.shape fx np.fft.fftfreq(nx, dpixel_size) # 空间频率坐标 fy np.fft.fftfreq(ny, dpixel_size) FX, FY np.meshgrid(fx, fy) # 传递函数 H(fx, fy) exp(jkz * sqrt(1 - (lambda*fx)^2 - (lambda*fy)^2)) k 2 * np.pi / wavelength with np.errstate(invalidignore): term 1.0 - (wavelength * FX)**2 - (wavelength * FY)**2 term np.where(term 0, 0, term) # 隐逝波成分置零 H np.exp(1j * k * z * np.sqrt(term)) # 频谱滤波仅提取 1 级号频项 spectrum fftshift(fft2(hologram)) center (ny // 2, nx // 2) # 根据实验设置号频项的位置这里是示例值 signal_center (center[0] 30, center[1] - 25) window_size (128, 128) mask np.zeros_like(spectrum) y0, x0 signal_center dy, dx window_size[0] // 2, window_size[1] // 2 mask[y0-dy:y0dy, x0-dx:x0dx] 1 filtered spectrum * mask # 平移频谱使号频项回到中心 shifted ifftshift(filtered) # 重建传播 field ifft2(shifted) * H return field # 参数配置 hologram cv2.imread(hologram.png, cv2.IMREAD_GRAYSCALE).astype(np.float32) wavelength 650e-9 # 激光二极管波长 z 0.12 # 物距 12 cm pixel_size 3.45e-6 # 相机像素尺寸 field angular_spectrum_reconstruction(hologram, wavelength, z, pixel_size) amplitude np.abs(field) phase np.angle(field) cv2.imwrite(reconstruction_amp.png, (amplitude / amplitude.max() * 255).astype(np.uint8))这段代码里值得逐项解释的参数有三个。第一个是信号频位置 signal_center它的物理含义是全息图频谱中号频项偏离零频中心的像素数与参考光夹角直接相关。不会算可以先从频谱图里用鼠标读出峰值坐标也可以用公式 Δfx sin(θ)/λ 推算。第二个是窗口大小 window_size太大会把共轭像的部分频谱圈进来太小则会损失物光的高频分量。保守做法是取号频峰半高宽度的 3-5 倍。第三个是隐逝波项的处理当 1 - (λfx)² - (λfy)² 0 时传递函数对应衰减波而非传播波直接置零可以避免数值发散。3.4 重建结果的判读从振幅像和相位像中能看到什么运行上面的代码会得到两个输出振幅像和相位像。振幅像反映了物体的吸收或散射强度分布相位像则记录了光通过物体后的光程差变化。对于透射式样品相位分布 φ(x,y) 2π·Δn·d / λ其中 Δn 是样品与周围介质的折射率差d 是样品厚度。这就是数字全息能做定量相位成像的物理基础。在实例演示中最典型的判读方式是观察振幅像中物体轮廓是否清晰。如果模糊加大 z 值或者减小 z 值重跑——因为实验中测量的 z 可能有误差。观察相位像中物体内部的灰度变化。均匀区域相位应接近常数不应该出现横向的渐变条纹。如果振幅像中看到重影或双重轮廓说明频谱滤波窗口混入了共轭像的频谱缩小 window_size。4. 重建参数的标定方法距离、波长与像素尺寸不是随便填的4.1 距离 z 的精确标定毫米误差对相位重建的影响有多大z 是重建结果对误差最敏感的参数。可以从相位传播公式中估算角谱传递函数的相位项是 kz√(1 - λ²f²)对 z 求导得到 k√(1 - λ²f²)当 z 100 mm、λ 650 nm 时1 mm 的距离误差在最大空间频率处会引入数千弧度的相位偏差。这意味着直接用尺子量出来的距离精度通常不足以支撑定量相位分析。我在实验中常用的标定方法是自动对焦扫描。做法很简单def autofocus_metric(field): 基于 Tenengrad 梯度的清晰度评价函数 amplitude np.abs(field) gx cv2.Sobel(amplitude, cv2.CV_32F, 1, 0, ksize5) gy cv2.Sobel(amplitude, cv2.CV_32F, 0, 1, ksize5) return np.mean(gx**2 gy**2) best_z, best_score 0, 0 for z_candidate in np.linspace(0.08, 0.16, 40): # 80-160 mm 扫描 field angular_spectrum_reconstruction(hologram, wavelength, z_candidate, pixel_size) score autofocus_metric(field) if score best_score: best_score, best_z z_candidate, score print(最佳对焦距离: {:.1f} mm.format(best_z * 1000))扫描步长设置为 2 mm经验上足够找到最佳对焦点。值得注意的是自动对焦的 z 值不一定等于物理距离它实际上是把球面参考波的曲率误差也一并补偿掉了。所以在系统中如果使用了非平行参考光自动对焦出的 z 反而是更准确的传播距离。4.2 波长与像素尺寸的系统误差修正4.2.1 激光二极管的实际波长偏离标称值激光二极管的标称波长通常对应 25 摄氏度工作温度实际波长温漂约为 0.2-0.3 nm/K。650 nm 标称值的二极管在 40 度壳温下可能实际输出 654 nm对应 0.6% 的相对波长误差。这个误差不会破坏重建像但会导致横向放大率标定不准。修正方式是用光谱仪实测波长或者在系统中加入已知周期的标准光栅用重建出的光栅周期反推实际波长。4.2.2 像素尺寸的最好来源不是规格书工业相机的标称像素尺寸存在制造公差阵列总宽度的误差通常在 0.1%-0.5% 之间。对重建的影响体现在放大率上全息图的横向尺寸是 N·Δx如果实际 Δx 与设定值不符重建像的横向缩放就会有偏差。更可靠的办法是用标准尺或已知间距的分辨率板做标定重建出分辨率板的像量出某一组线对的像素间距与已知物理间距相除得到实际像素尺寸。4.3 频谱滤波参数的自动化选择4.3.1 自动定位号频峰的位置手动在频谱图上找号频峰所在位置可行但如果需要批量处理多组数据就要用自动定位。常见做法是计算频谱功率谱先屏蔽中心区域零频周围约 30 像素再找全局最大峰值。spectrum np.abs(fftshift(fft2(hologram))) power spectrum**2 ny, nx power.shape center_mask np.zeros_like(power) cy, cx ny // 2, nx // 2 center_mask[cy-30:cy30, cx-30:cx30] 1 masked_power power * (1 - center_mask) peak_y, peak_x np.unravel_index(np.argmax(masked_power), power.shape)4.3.2 滤波窗口形状对重建像质量的影响矩形窗在频域上的截断等价于空域卷积 sinc 函数会在重建像边缘产生振铃。改用汉宁窗或高斯窗可以有效抑制这种现象。窗口半径的选择原则是覆盖号频峰的主瓣即可旁瓣部分用窗函数的衰减边缘自然过渡。def gaussian_filter_mask(shape, center, sigma): y, x np.ogrid[:shape[0], :shape[1]] dist_sq (y - center[0])**2 (x - center[1])**2 return np.exp(-dist_sq / (2 * sigma**2))sigma 的取值与空间频率带宽的关系是sigma 越大保留的高频成分越多重建像分辨率越高但混入共轭像噪声的风险也越大。从 σ 30 像素开始试逐次增加直到振幅像边缘出现环形纹然后回退 10 个像素。5. 进阶实践预放大数字全息、相位解包裹与多波长消噪5.1 用显微物镜做预放大把分辨率从系统级推到衍射极限前述光路中物体直接被激光照明属于无透镜数字全息结构分辨率受限于相机的数值孔径 NA_det Δx / (2λz)。以 3.45 μm 像素、12 cm 距离计算分辨率约 4 μm只能看清百微米级特征。如果想对细胞或微结构成像需要在物光臂加入显微物镜做预放大。预放大光路的本质是显微物镜先把物体放大 M 倍成一个实像这个像再与参考光干涉被相机记录。此时相机记录的有效 NA 等于物镜的 NA 除以放大倍率系统分辨率由物镜决定而不是由像素尺寸决定。物镜的放大倍率选择需要让物镜出射的艾里斑尺寸匹配 3-5 个像素太小会欠采样太大会损失视场。预放大全息的重建算法与无透镜情况相同但重建出的相位场包含物镜引入的固有球面相位需要用空场校准扣除不放样品记录一张全息图重建出相位参考场 φ_ref再放样品记录重建出 φ_sample最终相位为 φ_sample - φ_ref。这种双次测量法即使在光路有像差的情况下也能获得高质量的定量相位图。5.2 相位解包裹跳过这一步三维形貌全是假的重建得到的相位是包裹在 (-π, π] 区间内的主值。如果物体厚度变化导致光程差超过一个波长相位图中就会出现 2π 跳变条纹。不解决包裹问题而直接做三维渲染看到的会是类似等高线地图的周期性条纹无法还原真实形貌。一维相位解包裹的基础公式是相邻值比较后加减 2π 的整数倍但在二维图像上噪声和断点会导致误差沿积分路径传播。实际演示中我推荐质量引导法其基本步骤如下def quality_guided_unwrap(phase, quality_map): 质量引导解包裹算法按质量从高到低逐点展开 # 实现要点 # 1. 用质量图选种子点质量最高像素 # 2. 使用优先队列每次取质量最高的相邻像素 # 3. 对每个像素用其已解包裹邻域的均值估计模糊度 # 4. 加上 2π * round((est - phase) / (2π)) 完成解包裹 pass质量图的计算可以用二阶偏导的倒数质量高的区域相位变化平缓质量低的区域相位变化剧烈或有噪声。需要留意的是解包裹误差是灾难性的——任何一个像素的错误都会沿传播路径扩散所以在解包裹前先用中值滤波窗口 3×3做平滑能显著降低误差概率。5.3 多波长消噪与拼接视场从单帧到工程化系统单波长数字全息的一个固有缺陷是相位模糊只要光程差大于一个波长就无法从单个相位图中判断绝对高度。用两个波长的激光分别采集全息图可以在合成波长 Λ λ1·λ2 / |λ1 - λ2| 上消除模糊。例如 632.8 nm 和 650 nm 的合成波长为 24 μm这意味着不模糊的测量范围从 0.3 μm 扩展到 12 μm。合成波长的实现方式是在两幅重建相位图之间做差再对差进行涨级判断。视场拼接则是另一个工程问题。数字全息的分辨率越高视场越小两者受限于空间带宽积这是一个硬约束无法同时突破。解决方法是采集多幅有重叠区域的全息图利用重建相位图的边缘特征做拼接。拼接时重叠区域的相位差异可以作为修正基准用最小二乘法消除相邻视场之间的倾斜项差异。对于刚完成数字全息实验实例演示的工程人员我的建议是先用本篇文章中的代码和参数跑通振幅重建确认光路和算法链路没有系统性问题再逐步加入相位解包裹、自动对焦和多波长功能。每一步的验证标准很明确——振幅像的轮廓应该清晰锐利相位像在平坦区域应该是平滑的渐变而非条纹状伪影合成波长测量值应该落在准确尺寸的 ±2% 以内。这些验证方法比任何理论推导都能更快地帮你发现实验系统中的问题所在。本文还有配套的精品资源点击获取
分享:

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

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