问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

快速傅里叶变换(FFT)的简单应用:提取信号中的主频率

创作时间:
作者:
@小白创作中心

快速傅里叶变换(FFT)的简单应用:提取信号中的主频率

引用
CSDN
1.
https://blog.csdn.net/weixin_40146921/article/details/122006305

快速傅里叶变换(FFT)是数字信号处理中的重要工具,可以用来分析信号的频率成分。本文将通过一个简单的例子,展示如何使用FFT来提取信号中的主频率。

测试信号生成

首先,我们生成一个含有大量噪声的测试信号。信号由两个不同频率的正弦波叠加而成,并添加了高斯白噪声。

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(-10, 10, 1 / 1e4)  # 时间序列
f1, f2 = 0.1, 200  # 两个信号的频率
noise = 10 * np.random.randn(len(t))  # 噪声信号

# 生成测试信号
y = 1.3 * np.sin(2 * np.pi * f1 * t) + 2.5 * np.cos(2 * np.pi * f2 * t) + noise

plt.figure()
plt.plot(t, y)
plt.xlabel("t")
plt.ylabel("y")
plt.show()

由于噪声很大,从时域图上几乎看不出信号的具体形态:

利用FFT提取主频率

接下来,我们使用FFT来分析信号的频率成分。具体实现如下:

from scipy.fft import fft, fftfreq

def analyse_freq_and_amp(x: np.ndarray, y: np.ndarray):
    """
    分析不同频率谐波的幅值
    :param x: 时间序列
    :param y: 信号序列
    :return: 频率序列,幅值序列
    """
    n = len(x)
    sample_freq = (n - 1) / (x[-1] - x[0])  # 采样频率
    freqs = fftfreq(n, 1. / sample_freq)[:n // 2]
    amplitudes = 2. / n * np.abs(fft(y)[:n // 2])
    return freqs, amplitudes

freqs, amps = analyse_freq_and_amp(t, y)

plt.figure()
plt.plot(freqs, amps)
plt.xlabel("Freq./Hz")
plt.ylabel("Amplitude")
plt.show()

从频域图上可以看出,信号中有两个频率成分的幅值明显高于其他频率:

进一步放大观察,可以发现这两个频率成分分别位于0.1Hz和200Hz附近,对应的幅值约为1.3和2.5,这与我们生成信号时设置的参数完全一致。

完整代码

以下是完整的Python代码,包含了信号生成、FFT分析以及结果可视化:

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq

def analyse_freq_and_amp(x: np.ndarray, y: np.ndarray):
    """
    分析不同频率谐波的幅值
    :param x: 时间序列
    :param y: 信号序列
    :return: 频率序列,幅值序列
    """
    n = len(x)
    sample_freq = (n - 1) / (x[-1] - x[0])  # 采样频率
    freqs = fftfreq(n, 1. / sample_freq)[:n // 2]
    amplitudes = 2. / n * np.abs(fft(y)[:n // 2])
    return freqs, amplitudes

if __name__ == "__main__":
    t = np.arange(-10, 10, 1 / 1e4)
    f1, f2 = 0.1, 200
    noise = 10 * np.random.randn(len(t))  # 噪声信号

    # 生成测试信号
    y = 1.3 * np.sin(2 * np.pi * f1 * t) + 2.5 * np.cos(2 * np.pi * f2 * t) + noise

    freqs, amps = analyse_freq_and_amp(t, y)

    plt.figure()
    plt.plot(t, y)
    plt.xlabel("t")
    plt.ylabel("y")

    plt.figure()
    plt.plot(freqs, amps)
    plt.xlabel("Freq./Hz")
    plt.ylabel("Amplitude")
    plt.show()

通过这个简单的例子,我们可以看到FFT在信号处理中的强大能力。它不仅可以帮助我们识别信号中的主要频率成分,还可以为进一步的信号处理和分析提供基础。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号