我是信号处理方面的新手,需要您的帮助。
我已经从TI AFE4490获得了10秒的原始PPG(光电容积描记图)信号。我的硬件已经过校准,我每秒使用250个样本来记录这些信号。最后我获得了2500点。
您可以在下面看到图像,点和代码。
顶部:我的原始PPG信号-底部:尝试应用FFT:
代码:
RED, IR, nSamples, sRate = getAFESignal()
period = 1/sRate
plt.figure(1)
plt.subplot(2,1,1)
x = np.linspace(0.0, nSamples*period, nSamples)
y = IR
plt.xlabel("Time (s)")
plt.ylabel("Voltage (V)")
plt.plot(x,y)
plt.subplot(2,1,2)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*period), nSamples//2)
plt.xlabel("Frequency (Hz)")
plt.ylabel("Gain")
plt.plot(xf, 2.0/nSamples * np.abs(yf[0:nSamples//2]))
plt.grid()
plt.show()
函数getAFEsignal()
只是一个读取.txt文件并将其全部放入两个numpy数组的函数。
在这里您可以找到.txt文件:Raw signal file
如您所见,我没有正确应用FFT,我需要这样做才能发现需要过滤的频率。您知道我在做什么错吗?是否有可能在此信号上应用FFT?
答案 0 :(得分:3)
好消息是您对FFT的计算很好。您在时域中显示的数据具有相当强的低频成分。相应地,您得到的频域图显示出一个接近0Hz的尖峰。
主要问题在于如何绘制结果。为了根据对时域波形的直觉更好地了解在频域中可能看到的内容,您需要重新调整每个轴的比例。特别是,在显示的时间范围内,您可能会注意到持续时间约为0.25秒的模式 可能长达几秒钟。那将对应于大约0-5Hz的频率范围。然后,将重点放在该范围而不是显示整个0-125Hz频谱将是有意义的。这可以通过如下设置x轴限制来实现:
plt.xlim(0,5) # set x-axis limits from 0 to 5Hz
类似地,对于y轴,您需要考虑到小幅度的频率分量(在线性范围内变得越来越难以注意到)仍然可以对时域信号产生非常明显的影响。因此,通常希望以对数分贝标度显示频域幅度。可以按照以下步骤进行操作:
plt.plot(xf, 20*np.log10(2.0/nSamples * np.abs(yf[0:nSamples//2])))
最后,如果您希望更好地查看某些特定频率分量的贡献而又不受其他频率分量的spectral leakage干扰,则可能需要考虑在计算FFT之前对时域信号进行预滤波。例如,如果要消除恒定的信号偏置,缓慢的〜0.1Hz变化和频率大于10Hz的噪声的影响,则可以使用以下内容:
import scipy.signal
b,a = signal.butter(4, [0.25/sRate, 10/sRate], btype='bandpass')
y = signal.filtfilt(b,a,signal.detrend(IR, type='constant'))