使用Numpy恢复正弦波相移时存在数值噪声问题
FFT计算位移时出现数值噪声,结果与预期偏差明显
我运行以下代码时,预期displacement_sim的值应该和displacement几乎完全相等,但实际结果存在明显的数值噪声。当前运行脚本得到的计算值是9.654553207983893e-10,而预期值是1e-9。我已经尝试过使用余弦的精确实现,但没有效果,推测问题出在FFT环节,想问问有没有人遇到过类似情况?
import numpy as np import matplotlib.pyplot as plt import scipy.signal as sig plt.close("all") #simulation lambda_start = 1300e-9 lambda_end = 1350e-9 k_start = 2*np.pi / lambda_start k_end = 2*np.pi / lambda_end f_d = 8192.0 / 2.0**20.0 depth = 200e-6 displacement = 1e-9 records = 8192 sweep_length = 4000 k = np.linspace(k_start, k_end, sweep_length) vib = displacement * np.cos(2 * np.pi * f_d * np.linspace(0,records - 1, records)); kk, vv = np.meshgrid(k, vib) inter = 30000*(np.cos(2*(kk)*(depth + vv)) + 1) plt.plot(inter[::100].T) displacement_sim = (1325e-9 / (4*np.pi)) * np.abs(np.fft.fft(np.unwrap(np.angle(np.fft.fft(inter)[:,11]))))[64] / (4096)
几个可能的问题和调整方向:
- FFT频率泄漏问题:你的目标振动频率
f_d ≈ 7.8125e-3 Hz,采样频率默认是1Hz(因为vib的时间轴是从0到8191,间隔1),FFT的bin宽度是1/8192≈1.22e-4Hz,虽然目标频率刚好对应第64个bin,但实际计算中可能因为浮点精度或信号建模的微小偏差,导致能量泄漏到相邻bin,影响幅值准确性。试试给时域信号加汉宁窗,比如在做FFT前把inter[:,11]乘以np.hanning(records),能大幅减少泄漏。 - 相位unwrap的可靠性:你只取了第12个k点的信号做处理,先确认这个点的时域信号是否正常——单独提取
inter[:,11]画个图,看看是不是符合预期的带直流分量的余弦振动,有没有异常波动。如果这个信号本身有噪声,unwrap后的相位也会不准。 - 幅值计算的系数核对:你的
displacement_sim公式里用了1325e-9(中间波长)和除以4096,再仔细推导一下公式逻辑:FFT对实信号的幅值需要乘以2/N才能对应时域的幅值,这里4096是8192/2,但前面的np.abs(np.fft.fft(...))有没有考虑到这一点?另外,中间波长用1325e-9是否准确?可以换成(lambda_start+lambda_end)/2计算,避免硬编码的误差。 - 信号建模的细节:
meshgrid生成的kk和vv,有没有确认2*kk*(depth+vv)这个相位的计算是正确的?比如是不是应该对应光学测量中的往返路径(通常往返路径的相位是4πk*位移),先确认物理模型的推导是否准确。
快速试一下这几步:
- 提取
x = inter[:,11],画时域图,看波形是否干净; - 给x加汉宁窗后再做后续的FFT和相位unwrap;
- 把
1325e-9换成(lambda_start + lambda_end)/2,重新计算系数。
内容的提问来源于stack exchange,提问作者dHubley
相关产品推荐
相关产品推荐

