干涉测量 绝对测量仿真模拟 MATLAB
咱们今天来聊点硬核但好玩的东西------用MATLAB手搓干涉测量的绝对测量仿真。这玩意儿在光学检测、精密加工领域可是基本功,但很多教材讲得跟天书似的,今天咱用代码把它拽下神坛。
先整点基本操作,搞个干涉条纹看看。上硬菜:
matlab
lambda = 632.8e-9; % 氦氖激光波长
d = 1e-3; % 被测物体厚度
theta = linspace(-0.1, 0.1, 1000); % 扫描角度
phi = 2*pi/lambda * d * theta.^2; % 相位差计算
I = 0.5*(1 + cos(phi)); % 干涉强度公式
figure;
plot(theta*1e3, I);
xlabel('角度 (mrad)');
ylabel('相对强度');
title('理想干涉条纹');
这段代码把干涉条纹的核心逻辑给扒干净了。注意看theta的平方项,这玩意儿对应着被测面形的二次相位变化。咱们故意用角度扫描代替位移变化,这样仿真出来的条纹更接近实际干涉仪的工作模式。
不过现实中的干涉仪哪能这么干净?上点噪声才真实:
matlab
noise_level = 0.1; % 噪声强度
I_noisy = I + noise_level*randn(size(I)); % 加性高斯噪声
% 移动平均降噪
window_size = 15;
b = (1/window_size)*ones(1,window_size);
I_filtered = filtfilt(b, 1, I_noisy);
subplot(2,1,1);
plot(theta*1e3, I_noisy);
title('带噪声干涉条纹');
subplot(2,1,2);
plot(theta*1e3, I_filtered);
title('滤波后条纹');
这里有个骚操作------用filtfilt实现零相位滤波。比普通滤波强在哪?它正反各滤一次,消除相位延迟,这对后续相位解包至关重要。不信你换成普通filter函数试试,相位曲线能给你扭成麻花。
重头戏来了,相位解包和绝对测量:
matlab
% 相位提取
phase_wrapped = acos(2*I_filtered - 1); % 包裹相位
phase_unwrapped = unwrap(phase_wrapped); % 解包裹
% 绝对面形计算
n = 1.5; % 材料折射率
surface_profile = phase_unwrapped * lambda/(4*pi*(n-1));
% 理论值对比
theory_profile = d*theta.^2/(2*(n-1));
figure;
plot(theta*1e3, surface_profile*1e6, 'b');
hold on;
plot(theta*1e3, theory_profile*1e6, 'r--');
legend('仿真结果','理论值');
xlabel('角度 (mrad)');
ylabel('面形高度 (μm)');
title('绝对测量结果对比');
注意看acos之后的相位包裹问题。unwrap函数虽然智能,但在低信噪比区域可能会翻车。实战中老司机会加个中值滤波预处理,这里为了代码简洁就省了。最终结果用微米量级显示,这个尺度刚好对应光学元件的面形精度要求。
最后说个坑:当theta范围太大时,二次项模型会失效。这时候得改用Zernike多项式拟合,不过那就是另一个故事了。留个思考题------如果把theta改成非对称分布,仿真结果会出现什么特征?动手改改代码参数,比看十篇论文都管用。
