摘要:傅立叶变换是一个强大的概念,用于各个领域,从纯数学到音频工程甚至金融。
傅立叶变换是许多应用程序中的重要工具,尤其是在科学计算和数据科学中。结果,Scipy长期以来一直在提供其实施和相关的转换。从本质上讲,Scipy提供了Scipy.fftpack模块,但后来他们更新了。他们的实现并将其移至scipy.fft模块。
Scipy充满了功能。对于图书馆的更一般介绍,请检查Scientific Python:使用Scipy进行优化。
在开始之前,您需要安装Scipy和Matplotlib。您可以通过以下两种方法之一执行此操作:
您可以验证安装在终端中的python是否有效,并运行以下代码:
该代码将导入Scipy和Matplotlib的位置并打印模块。您的计算机可能会显示不同的路径,但是只要它打印出路径,安装就会成功。
现在已安装Scipy!是时候看到Scipy.fft和Scipy.fftpack之间的区别了。
查看Scipy文档时,您可能会遇到两个看起来非常相似的模块:
scipy.fft模块更新,您应该更喜欢阅读有关scipy.fftpack分发指令的分发指令中的变化的更多信息,但是这里有一个快速摘要:摘要:摘要:
除非您有足够的理由使用scipy.fftpack,否则应坚持使用scipy.fft。
Scipy的快速傅立叶变换(FFT)实现了更多的功能,并且比Numpy的实现更有可能修复错误。如果您有选择,则应使用Scipy。
Numpy保持FFT实现以实现向后兼容性,尽管作者认为最好像傅立叶变换一样将Scipy放入Scipy。有关更多详细信息,请参阅Scipy上常见问题的答案。
傅立叶分析是研究如何将数学函数分解为一系列简单的三角函数。版本转换是该领域的工具,用于将函数分解为其组件频率。
好吧,这个定义非常密集。就本教程而言,傅立叶变换是一种工具,可以使您获得信号并查看每个频率的功能。查看此句子中的重要术语:
下图是一些正弦波的频率和功率的直观演示:
峰值高频弦波更接近低频正弦波,因为它们重复的频率更高。低功率正弦波的峰值比其他两个正弦波小。
为了更具体地解释这一点,假设您将傅立叶变换使用给同时在钢琴上弹奏三张笔记的人。恢复频谱将显示三个峰值值,每张音符。音符的频率强度将低于其他两个。
这就是视觉上的钢琴示例:
钢琴上最高的音符比其他两个音符更安静,因此该音符的光谱具有较低的峰值。
傅立叶变换在许多应用程序中都是有用的。例如,Shazam和其他音乐识别服务使用傅立叶来识别歌曲。
JPEG压缩了傅立叶变换的变体,以删除图像的高频组件。VOICE识别使用傅立叶变换和相关转换来恢复原始音频的口语。
通常,如果您需要查看信号中的频率,则需要执行傅立叶变换。如果很难处理时间域中的信号,那么值得尝试将其移至频率域中以傅立叶变换。部分,您将了解时域和频域之间的差异。
在本教程的其余部分中,您将看到一词时域和频域。这些术语是指查看信号的两种不同方式,即它们的组件频率或随着时间变化的信息。
在时间域中,信号是随着时间的推移(x轴)的幅度(y轴)的浪潮。您可能习惯于在时间域中看到图形,例如:
这是一些音频图像,它是一个时域信号。水平轴表示时间,垂直轴表示幅度。
在频域中,信号由一系列频率(x轴)表示,并且每个频率具有相关的功率(y轴)。下图是上述通过上述通过傅立叶变换后的音频信号:
在这里,先前的音频信号由IT频率表示。底部的频率具有相关的功率来生成您看到的频谱。
有关频域的更多信息,请查看Deepai词汇表。
傅立叶变换可以细分为不同类型的转换。最基本的细分是基于转换操作的数据类型:连续函数或离散函数。本教程只能处理离散的傅立叶变换(DFT)。
即使在本教程中,您也经常看到DFT和FFT的两个术语。但是它们并不完全相同。快速傅立叶变换(FFT)是用于计算离散傅立叶变换(DFT)的算法,而DFT是转型本身。
您将在scipy.fft库中看到的另一个区别是不同类型的inputs.fft()接受复数值输入,而rfft()接受实际数字输入。)部分了解复数和实数。
其他两个更改与DFT密切相关:离散字符串转换(DCT)和离散的鼻窦转换(DST)。您将在离散字符串和正弦转换部分中了解这些内容。
为了帮助您了解傅立叶变换以及可以使用的内容,您将过滤一些音频。首先,您将创建一个带有高音嗡嗡声的音频信号,然后您将使用傅立叶变换来消除嗡嗡声。
Sangar波有时被称为纯声音,因为它们代表单个频率。您将使用正弦波来产生音频,因为它们会在家谱中形成不同的峰。
正弦波的另一个优点是可以用numpy直接生成它们。如果您以前从未使用过numpy,那么您可以看到什么是numpy?
这是产生正弦波的一些代码:
您将来将介绍两个带有Numpy和Matplotlib的常数:您可以定义两个常数:
接下来,您定义一个函数来生成正弦波,因为将来会多次使用它。此功能使用该频率,然后FREQ返回X和Y值的X和Y值来绘图波形。
正弦波的x坐标均匀分布在0和0之间,因此代码使用numpylinspace()生成它们。它需要一个起始值,终端值和要生成的样本数量。设置端点= false对于傅立叶的正常工作非常重要,因为它假设信号是周期性的。
np.sin()计算每个X坐标的正弦函数值。归纳乘以在此频率下振荡频率的结果,乘积为2π,以将输入值转换为弯曲。
注意:如果您以前从未学过太多三角形,或者需要查看,请检查Ke Khan Institute的三角课程。
定义函数之后,您可以使用它来生成2 Hz正弦波,该波持续5秒并使用matplotlib绘制它。您的正弦波映射应如下:
X轴代表秒内的时间。由于每秒有两个峰,您可以看到正弦波每秒两次振荡。该弦波的频率太低而无法听到,因此,在下一部分中,您将产生一些较高的频率正弦波,您将了解如何混合它们。
好消息是,混合音频信号仅包含两个步骤:
将信号混合在一起之前,您需要生成它们:
此代码示例中没有新的内容。它生成分配给变量nice_tone的介质和treble noise_tone。加在一起。请请注意,您使用该行(_)丢弃X返回的值generate_sine_wave()。
下一步是标准化或缩放信号以适应目标格式。由于您将稍后存储音频,因此目标格式为16位整数,范围从-32768到32767:
在这里,将代码缩放为混合_tone,使其适用于16位整数,然后使用Numpy的NP.Int16。除混合_tone以外,在-1和-1和1之间的缩放1和1。当此信号乘以32767时,它在-32767和32767之间进行缩放,大约是NP.Int16。信号的结构更清晰。
您的情节应该像这样:
信号看起来像是正弦波。您看到的正弦波是您生成的400 Hz音调,而失真为4000 Hz音调。如果您仔细观察,您会发现失真是正弦波形状的。
要收听音频,您需要将其存储为可以读取为音频播放器的格式。最简单的方法是使用Scipy的wavfile.write方法将其存储在WAV文件中。16 -bit Integer是标准数据类型WAV文件的内容,因此您需要将信号标准化为16位整数:
该代码将写入MySineWave.wav。您可以在Python脚本的目录中运行文件。然后,您可以使用任何音频播放器甚至Python收听此文件。您会听到较低的音调和高音调。这些是您的400 Hz和4000 Hz正弦波。
完成此步骤后,您的音频示例准备就绪。下一步是使用傅立叶变换来删除高音!
是时候在生成的音频上使用FFT.FFT是一种实现傅立叶变换的算法。它可以计算时间域中的信号频谱,例如您的音频:
该代码将绘制计算出的音频傅立叶变换并绘制它。在分解之前,请查看其产生的图:
您可以在两个峰和正频率下的两个峰值中看到这些峰值的镜子。正频率的峰为400 Hz和4000 Hz,与输入音频的频率相对应。
傅立叶变换已将您的复杂信号和弱信号转换为所包含的频率。由于您只输入两个频率,只有两个频率出现。阴性对称性是将真实值输入输入到傅立叶变换中的副作用,但是您会听到更多信息。稍后相关信息。
在前几行中,您导入scipy.fft以后将使用的函数,并为存储信号中样本总数定义一个可变n。
之后,这是最重要的部分。计算傅立叶变换:
该代码调用两个非常重要的功能:
Box A已被分组,就像一个值范围的直方图一样。有关bin的更多信息,请参见此信号处理堆栈交换问题。对于本教程的目的,您可以将它们视为单个值。
一旦获得了傅立叶变换的结果及其相应的频率,就可以绘制它们:
该代码的有趣部分是绘制之前的YF处理。
一个数字是一个数字,其中有两个部分,即真实和虚拟部分。有许多原因定义此类数字,但是您现在需要知道的是它们存在。
数学家通常以A + BI的形式写复数写作。其中,A是真实的部门,B是虚拟的部分。我后来代表B是虚拟编号。
注意:有时您会看到我写的复数,有时您会看到用j编写的复数,例如2 + 3 i和2 + 3 j。两个是相同的,但是我被数学家和J使用了。工程师使用。
有关复杂数字的更多信息,请检查Ke Khan Academy的课程或数学非常有趣的页面。
因为有两个部分,所以它们的频率绘制及两个维轴上的频率要求您从它们中计算一个值。这是Np.Abs()出现的位置。),这是两个数字的整体大小,重要的是一个值。
注意:顺便说一下,您可能已经注意到,返回的最大频率超过20,000 Hz,即22050Hz。此值恰好是我们采样率的一半,称为Nequest频率。
这是信号处理中的一个基本概念,这意味着您的采样率必须至少是信号的最高频率的两倍。
FFT()的频谱输出反映了Y轴,因此负半轴是正半的镜子。这对称是由转换输入(不是复数)引起的。
您可以使用此对称性来通过仅计算它来使傅立叶变换更快。Scipy.fft使用rffff()。
非常出色的rfft()是,它是fft()。记住以前的FFT代码:
更改为rfft(),代码基本上保持不变,但是有几个关键更改:
由于RFFT()仅返回输出fft()的一半,因此它使用不同的函数来获得频率映射,rfftfreq()而不是ffreq()。
rfft()仍会产生复杂的输出,因此绘制其结果的代码保持不变。但是,该图应在下面显示,因为负频率将消失:
您会看到上面的图只是FFT().rfft()生成的频谱的正侧,从不计算频谱的负半,这使其与fft()进行比较。
useingrfft()的fft()可以比使用的速度快两倍,但是某些输入长度比其他输入长度快。如果您知道只能使用实数,那么这是一种值得理解的速度技术。
现在,您有了信号范围,您可以继续过滤它。
Fourier转换的优点之一是它是可逆的,因此,当您将其转换回TIME域时,您将在频域中的信号中进行的任何更改。您将使用它来过滤音频并删除高频。
警告:本节中所示的过滤技术不适用于现实世界的信号。有关原因的解释,请参阅避免过滤陷阱部分。
返回值rfft()表示每个频率仓库的功率。如果将给定垃圾箱的功率设置为零,则垃圾箱中的频率将不再出现在生成的时域信号中。
长度XF,最大频率和频率间隔的事实均匀分布。您可以计算目标频率的索引:
然后,您可以将YF设置为围绕目标频率的索引,以摆脱它:
您的代码应如下生成:
由于只有一个峰,它似乎可以工作!接下来,您将使用傅立叶变换回到时域。
针对FFT的应用类似于应用FFT:
由于您使用的是rfft(),因此您需要使用irfft()应用反向。
如您所见,现在您的正弦波用400 Hz振荡,并且成功消除了4000 Hz的噪声。
再一次,您需要在将信号写入文件之前进行标准化。
当您收听此文件时,您会听到令人讨厌的噪音消失了!
以上示例更多地用于教育目的,而不是实际使用。复制现实世界中的过程(例如音乐)的过程可能会引入更多的嗡嗡声,而不是消除。
在现实世界中,您应该在scipy中使用过滤器设计功能。信号软件包过滤信号。Filter是一个涉及大量数学的复杂主题。要进行详细的介绍,请检查科学家和科学家的数字信号处理指南和工程师。
如果scipy.fft不了解离散字符串变换(DCT)和离散的鼻窦变换(DST),则该模块上的教程将不完整。这两个更改与傅立叶变换密切相关,但它们是完全计算的。他们将一个实际值函数用作输入,并生成另一个实际值函数作为输出。
Scipy实施到dct()和dst().i*and*n变体是逆和?的功能尺寸,它们是分开的。
DCT和DST有点像傅立叶变换的两半。这不是完全正确的,因为数学要复杂得多,但这是一个有用的心理模型。
因此,如果DCT和DST是傅立叶变换的一半,为什么它们有用?
一方面,它们比完整的傅立叶变换要快,因为它们已经有效地完成了一半的工作。它们甚至比RFFT()更重要。最重要的是,它们完全是实数,因此您不必担心多元化。
在学习如何在它们之间进行选择之前,您需要了解均匀的功能和魔术功能。均匀的函数是y轴对称的,奇数函数与原始点对称有关。要想象一下,请参阅以下图表:
您会看到偶数函数对y轴是对称的。奇数函数对y = -x是对称的,这被描述为对原点的对称。
当您计算傅立叶变换时,您假装正在计算它的函数是无限的。完整的傅立叶变换(DFT)假定输入函数重复重复。该函数通过偶尔的对称性扩展,并且DST假定其通过奇数对称性扩展。
下图说明了每个转换如何想象函数扩展到无穷大:
在上图中,DFT根据原始内容重复该功能。DCT垂直镜像功能将其扩展,而DST则是水平镜像。
请注意,DST的隐式对称性可能会引起该功能的显着跳跃。这些函数被称为不连续,并在结果频谱中产生更高的频率组件。因此,除非您知道数据很奇怪,否则您应该使用DCT而不是DST。
DCT非常常用。还有更多示例,但是JPEG,MP3和WebM标准使用DCT。
傅立叶变换是一个强大的概念,用于各个领域,从纯数学到音频工程甚至金融。
本文分享了华为云社区的诚意,作者:Yuchuan。