【数字信号处理】一文讲清FFT(快速傅里叶变换)

2024-09-06 20:20

本文主要是介绍【数字信号处理】一文讲清FFT(快速傅里叶变换),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

    • 快速傅里叶变换(Fast Fourier Transform,FFT)
      • FFT的背景
      • 快速傅里叶变换(Fast Fourier Transform,FFT)
      • DFT的数学表达
      • 实际计算
      • 重要性和应用
      • 频谱泄露、频谱混叠
      • 奈奎斯特采样定理
      • 参考链接

快速傅里叶变换(Fast Fourier Transform,FFT)

FFT的背景

  • 1、为什么要时域→频域频率?50Hz+频率120Hz正弦波信号叠加,再叠加一些随时间变换的干扰信号(噪声),信号时域上的波形如图2- 1(左)所示。
    显然,从图中很难看出真正的有效信息,更无法直接过滤干扰信号。若对叠加信号进行离散傅里叶变换处理,将时域波形→频域图,如图2- 1(右)为变换后的频谱图。此时便很容易分辨出真正有效的频率段是在50Hz和120Hz,而其它频率都是干扰信息。
    在这里插入图片描述
  • 2、那么问题来了,怎样将时域→频域呢
    于是出现了大神傅里叶。他提出了——离散傅里叶变换(Discrete Fourier Transform,DFT)是一种基础的数字信号处理算法,它将一个离散的信号从时域转换到频域,使得我们可以分析复杂信号中的频率成分。
    在这里插入图片描述
  • ???傅里叶变换是啥玩意?用人话来说,“把信号比喻成一件衣服,任何一块布都可以由不同颜色的线织成,远看这张比布我们不知道是由哪些颜色的线织成的,但如果把布料拆散成一条条线,是不是就可以清晰地分析出所用线的颜色”
  • 同理,傅里叶认为任何一个信号都可以用很多个不同幅度、频率的正弦波/余弦波叠加而成,如果把这些“正弦波/余弦波”分离出来,就可以分析这些波的频率。如果再把这些频率画在如图2- 1(右)的频谱分布图上,就直观地实现了时域→频域

傅里叶变换(法语:Transformation de Fourier,英语:Fourier transform,缩写:FT)是一种线性变换,通常定义为一种积分变换。
其基本思想是一个函数可以用(可数或不可数,可数的情况对应于傅里叶级数)无穷多个周期函数的线性组合来逼近,从而这些组合系数在保有原函数的几乎全部信息的同时,还直接地反映了该函数的“频域特征”。——维基百科

在这里插入图片描述

  • 3、说的简单,那我算起来该怎么算呢
    在现实世界中,一条连续的信号需要经过采样,变成一个个离散的信号后,才能用计算机计算。
    用到的算法就是“离散傅里叶变换(Discrete Fourier Transform,DFT)”。
    但是离散傅里叶变换的计算量极为庞大,能算,但是太慢!记住就行,因为会用到很多的乘法、加法运算,计算机实现乘法很麻烦!

(有兴趣可以看看为什么计算量大)一个N点复数序列x[n]的离散傅里叶变换定义为公式(3-1)所示,在计算N点序列x[n]的DFT时,每计算一次频率分量应进行N次复数乘法运算以及N-1次复数加法运算,故需要N2次复数乘法运算和(N-1)N次复数加法运算才能获取N个频率分量X[k][28]。由此看来,随着N值增加,信号处理中离散傅里叶变换的运算量会变得极为庞大,从而难以满足实时性的需求。
在这里插入图片描述

快速傅里叶变换(Fast Fourier Transform,FFT)

于是便出现了快速傅里叶变换(Fast Fourier Transform,FFT),说白了就是一类快速的计算离散傅里叶变换的方法。代表者是1965年Cooley(库利)和Tukey(图基)提出的FFT,可以将计算N点序列DFT的复乘次数降低到(N/2)log2N。

  • FFT假设输入信号是周期性的,即它会将一个有限长度的序列视为一个无限长的周期信号。当我们对一个有限长度的信号进行FFT时,实际上是在假设这个信号会无限重复。这个过程称为周期延拓。对于一个正弦波信号,如果你截取了一个完整的周期并进行FFT,得到的频谱将是该正弦波的特征频率。
  • 傅立叶变换(FFT)是一种算法,用于计算离散傅立叶变换(DFT)和其逆变换。
  • DFT的核心思想是任何时域信号都可以表示为一系列不同频率的正弦波和余弦波的加权和

DFT的数学表达

DFT将一个长度为 (N) 的时域序列 (x(n)) 转换为一个等长的频域序列 (X(k))。每个频域样本 (X(k)) 是通过以下公式计算得到的:

X ( k ) = ∑ n = 0 N − 1 x ( n ) e − i 2 π k n / N X(k) = \sum_{n=0}^{N-1} x(n) e^{-i 2 \pi k n / N} X(k)=n=0N1x(n)ei2πkn/N

  • 其中:

    • (x(n)) 是时域信号的第 (n) 个样本。
    • (X(k)) 是频域信号的第 (k) 个样本。
    • (N) 是总样本数。
    • (k) 是频率索引,从 0 到 (N-1)。
    • (e^{-i 2 \pi k n / N}) 是一个复数,表示在 (n) 时刻,频率为 (k) 的复指数函数的值。
  • 频域解释

在频域中,(X(k)) 的每个元素代表了信号在对应频率 (k) 处的复数幅度和相位。复数的模(绝对值)给出了该频率成分的强度,而其角度(相位)则表示该频率成分相对于时间原点的相位偏移。

实际计算

  • FFT算法执行

FFT算法的核心思想是通过分治法将信号分解为更小的部分,以下是具体步骤:

  • 分解信号

分成偶数和奇数部分:将输入信号分为偶数和奇数索引的部分。例如,对于信号 (x[n]),可以分解为:

  • 偶数部分
    x [ 0 ] , x [ 2 ] , x [ 4 ] , … x[0], x[2], x[4], \ldots x[0],x[2],x[4],

  • 奇数部分
    x [ 1 ] , x [ 3 ] , x [ 5 ] , … x[1], x[3], x[5], \ldots x[1],x[3],x[5],

  • 递归计算

递归调用FFT:对偶数和奇数部分分别递归调用FFT,直到信号长度为1(基准情况)。

  • 合并结果

  • 合并频谱:使用“蝴蝶运算”将偶数和奇数部分的FFT结果合并。对于每个频率成分 (k),合并公式为:

X [ k ] = E [ k ] + W N k O [ k ] X[k] = E[k] + W_N^k O[k] X[k]=E[k]+WNkO[k]

X [ k + N / 2 ] = E [ k ] − W N k O [ k ] X[k + N/2] = E[k] - W_N^k O[k] X[k+N/2]=E[k]WNkO[k]

其中,

  • (E[k]) 是偶数部分的FFT结果,

  • (O[k]) 是奇数部分的FFT结果,

  • (W_N^k = e^{-2\pi ik/N}) 是旋转因子。

  • 频谱分析

计算幅度和相位:从FFT的输出中提取频率成分,计算幅度和相位。幅度通常为复数结果的模:

∣ X [ k ] ∣ = ( R e ( X [ k ] ) ) 2 + ( I m ( X [ k ] ) ) 2 |X[k]| = \sqrt{(Re(X[k]))^2 + (Im(X[k]))^2} X[k]=(Re(X[k]))2+(Im(X[k]))2

  • 结果后处理

  • 频率分辨率:根据采样频率和信号长度计算频率分辨率。频率分辨率为

Δ f = f s N \Delta f = \frac{f_s}{N} Δf=Nfs

其中 (f_s) 是采样频率,(N) 是信号长度。

  • 绘制频谱:可以绘制频谱图,展示信号的频率成分。

重要性和应用

  • 例如,在音频处理中,DFT可以帮助识别音乐或语音信号中的不同音调和谐波;
  • 在通信系统中,它用于分析传输信号的频谱,以优化频道使用和减少干扰。

频谱泄露、频谱混叠

特征频谱泄露频谱混叠
定义信号频谱成分扩展到其他频率高频成分被误认为低频成分
原因窗口效应或信号截断采样频率不足
影响降低频率分辨率和准确性导致信号失真
解决方法使用更好的窗函数或增加信号长度提高采样频率
  • 频谱混叠就是采样频率不足,导致实现的频谱图“混叠”在一起,解决方法就是遵循奈奎斯特采样定理,即
    在这里插入图片描述
    在这里插入图片描述

  • 频谱泄露原因之一是窗函数(截取方法)不合适、信号长度不够,

因为FFT处理的是有限长的信号→
但是他会将有限的信号进行有限的周期延拓→
如果信号在延拓后不连续,就会在截断点引入高频成分
FFT处理高频成分时就会导致“泄露”到低频区域

在这里插入图片描述

奈奎斯特采样定理

  • 定义:奈奎斯特采样定理指出,为了准确重建一个带限信号,采样频率必须至少是信号最高频率的两倍。换句话说,如果一个信号的最高频率为 (f_{max}),则其采样频率 (f_s) 应满足:

f s ≥ 2 f m a x f_s \geq 2f_{max} fs2fmax

  • 关键点

    • 带限信号:信号的频谱在某一频率 (f_{max}) 之后为零。只有在这个频率范围内的信号可以被奈奎斯特采样定理所处理。

    • 重建:如果采样频率低于奈奎斯特频率(即 (2f_{max})),将会发生频谱混叠(aliasing),导致无法准确重建原始信号。

参考链接

  1. 傅里叶变换

这篇关于【数字信号处理】一文讲清FFT(快速傅里叶变换)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1143023

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

一文带你搞懂Python中__init__.py到底是什么

《一文带你搞懂Python中__init__.py到底是什么》朋友们,今天我们来聊聊Python里一个低调却至关重要的文件——__init__.py,有些人可能听说过它是“包的标志”,也有人觉得它“没... 目录先搞懂 python 模块(module)Python 包(package)是啥?那么 __in

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释