【问题标题】:Normalization - Signal with different sampling rates归一化 - 具有不同采样率的信号
【发布时间】:2020-03-20 09:04:20
【问题描述】:

我正在尝试解决信号处理问题。我有这样的信号

我的工作是使用 FFT 绘制频率与信号的关系图。这是我迄今为止编写的代码:

def Extract_Data(filepath, pattern):

    data = []
    with open(filepath) as file:
        for line in file:
            m = re.match(pattern, line)

            if m:
                data.append(list(map(float, m.groups())))


    #print(data) 
    data = np.asarray(data)
    #Convert lists to arrays
    variable_array = data[:,1]
    time_array = data[:,0]

    return variable_array, time_array

def analysis_FFT(filepath, pattern):

    signal, time = Extract_Data(filepath, pattern)
    signal_FFT = np.fft.fft(signal)

    N = len(signal_FFT)
    T = time[-1]

    #Frequencies
    signal_freq = np.fft.fftfreq(N, d = T/N)

    #Shift the frequencies
    signal_freq_shift = np.fft.fftshift(signal_freq)

    #Real and imagniary part of the signal
    signal_real = signal_FFT.real
    signal_imag = signal_FFT.imag
    signal_abs = pow(signal_real, 2) + pow(signal_imag, 2)

    #Shift the signal
    signal_shift = np.fft.fftshift(signal_FFT)
    #signal_shift = np.fft.fftshift(signal_FFT)

    #Spectrum
    signal_spectrum = np.abs(signal_shift)

我真正关心的是采样率。当您查看该图时,看起来前 ~0.002 秒的采样率与信号的其余部分不同。所以我在想也许我需要对信号进行归一化

但是,当我使用np.fft.fftfreq(N, d =T/N) 时,np.fft.ffreq 似乎假设信号在整个域中具有相同的采样率。所以我不确定如何使用np.fft 标准化信号。有什么建议吗?

干杯。

这就是我用偏移信号绘制偏移频率 [Hz] 时得到的结果

【问题讨论】:

  • 我认为问题是绘制频率与time,即频谱图。 Scipy有这样一个功能,scipy.signal.spectrogram。根据您提供的内容,无法看到采样率,并且实验数据通常不会改变采样率。您的信号最初具有较高的物理频率。因此,首先,绘制信号采样率以确保您拥有什么(从 1 到时间结束的所有 i 的 time[i+1]- time[i])。

标签: python-3.x signal-processing fft normalization frequency-analysis


【解决方案1】:

我生成了一个与您的相似的合成信号并绘制了图,就像您在整个过程中所做的频谱一样。你的情节很好,因为它涉及整个光谱,只是似乎没有给出绝对值。

import numpy as np
import matplotlib.pyplot as p
%matplotlib inline

T=0.05 #  1/20 sec
n=5000 #  5000 Sa, so 100kSa/sec sampling frequency
sf=n/T
d=T/n
t=np.linspace(0,T,n)  
fr=260 # Hz
y1= - np.cos(2*np.pi*fr*t) * np.exp(- 20* t)
y2= 3*np.sin(2*np.pi*10*fr*t+0.5) *np.exp(-2e6*(t-0.001)**2)
y=(y1+y2)/30

f=np.fft.fftshift(np.fft.fft(y))
freq=np.fft.fftshift(np.fft.fftfreq(n,d))

p.figure(figsize=(12,8))
p.subplot(311)
p.plot(t,y ,color='green', lw=1  ) 
p.xlabel('time (sec)')
p.ylabel('Velocity (m/s)')
p.subplot(312)
p.plot(freq,np.abs(f)/n)
p.xlabel('freq (Hz)')
p.ylabel('Velocity (m/s)');


p.subplot(313)
s=slice(n//2-500,n//2+500,1)
p.plot(freq[s],np.abs(f)[s]/n)
p.xlabel('freq (Hz)')
p.ylabel('Velocity (m/s)');

在底部,我放大了一点以显示两个主要频率分量。请注意,我们显示的是正频率和负频率(只有正频率,时间 2x 是物理频率)。 2600 Hz 处的高斯表示突发的频谱(高斯的 FT 为高斯)。 260 Hz 处的直线表示慢基频(正弦的 FT 是增量)。

然而,这隐藏了两个独立频率分量的时序,即在大约 2.6 kHz 开始时的短(在我的情况下为高斯)突发和大约 260 Hz 处的衰减低音。频谱图将信号的短片段 (nperseg) 垂直绘制为条纹,其中颜色表示强度。您可以在时间范围之间设置一些重叠,这应该是段长度的一部分。通过随时间堆叠这些条纹,您可以获得光谱随时间变化的图。

from scipy.signal import spectrogram 
f, t, Sxx =  spectrogram(y,sf,nperseg=256,noverlap=64)

p.pcolormesh(t, f[:20], Sxx[:20,:])
#p.pcolormesh(t, f, Sxx)
p.ylabel('Frequency [Hz]')
p.xlabel('Time [sec]')
p.show()

在 FFT 的帮助下尝试自己生成频谱图是有益的。否则,频谱图功能的设置一开始可能不是很直观。

【讨论】:

    猜你喜欢
    • 2017-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2022-08-08
    相关资源
    最近更新 更多