【scipy 基础】--傅里叶变换

这篇具有很好参考价值的文章主要介绍了【scipy 基础】--傅里叶变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

傅里叶变换是一种数学变换,它可以将一个函数或信号转换为另一个函数或信号,它可以将时域信号转换为频域信号,也可以将频域信号转换为时域信号。
在很多的领域都有广泛的应用,例如信号处理、通信、图像处理、计算机科学、物理学、生物学等。

它最大的功能是能够分析和提取信号的特征,将复杂的信号分解为简单的信号。
有人甚至说傅里叶变换是一种可以让我们看透世界本质的变换,将纷繁世界的表象中的本质显现出来。

1. 简介

从数学的角度来推导傅里叶变换的话,会涉及到很多的基本的数学概念,比如正交基,级数,正弦余弦函数等等。
这里主要是为了看懂和使用傅里叶变换,了解傅里叶变换中的主要概念即可,
Scipy库会帮助我们处理其中的细节。

举例来说,对于现实中遇到的如下一个原始信号(一般都是非周期性且无规律的):
【scipy 基础】--傅里叶变换
这样的信号,可以是声音,可以是气温变化,可以是心电图,甚至可以是股票涨跌情况等等。

原始的信号变化复杂,而且大部分情况都看不出什么规律。
这时,傅里叶变换就能发挥作用了,它能够将复杂无序的信号转换为一系列简单规则的信号。
比如上面的信号转换之后变成下面6个简单的信号
【scipy 基础】--傅里叶变换

另外,傅里叶变换是可逆的,它也能够将变换后的多个简单的信号还原成原始的复杂信号。

2. fft 模块

Scipy中处理傅里叶变换有2个子模块:fftfftpack
fftpack即将被淘汰,所以尽量使用fft模块。

fft模块中,傅里叶变换的主要函数有:

函数名 说明
fft 计算一维离散傅里叶变换
ifft 计算一维离散傅里叶逆变换
fft2 计算二维离散傅里叶变换
ifft2 计算二维离散傅里叶逆变换
fftn 计算N维离散傅里叶变换
ifftn 计算N维离散傅里叶逆变换

2.1. 变换示例

创建一个复合的信号:

import numpy as np
import matplotlib.pyplot as plt

# 生成 0~8pi 之间100个点
x = np.linspace(0, 8*np.pi, 100)

# 随便生成6个不同的正弦信号
y1 = np.sin(x)
y2 = 4*np.sin(2*x)
y3 = 2*np.sin(4*x)
y4 = 8*np.sin(0.3*x)
y5 = 6*np.sin(0.8*x)
y6 = 0.5*np.sin(5*x)

y = y1 + y2 + y3 + y4 + y5 + y6

plt.plot(x, y)
plt.show()

【scipy 基础】--傅里叶变换

下面通过一维傅里叶变换,看看得到的结果:

from scipy import fft as spfft

fft_result = spfft.fft(y)
print(fft_result.shape)
# 运行结果
(100,)

fft_result[1:11]
# 运行结果(显示前10个,总共100个)
array([ 99.548317    -0.j        , 273.43743482-274.69892934j,
       -10.91586207 +66.24943608j, 167.24328363-151.29814008j,
       -57.93543536 +49.80593353j, -30.50244642 +56.21303872j,
       -19.99077861 +37.24642604j, -13.54997057 +21.30562857j,
        35.119202  -161.91923934j, -17.17382544 +41.98143084j])


fft_result[-10:]
# 运行结果(显示后10个,总共100个)
array([-13.61273919 -29.66475047j, -17.17382544 -41.98143084j,
        35.119202  +161.91923934j, -13.54997057 -21.30562857j,
       -19.99077861 -37.24642604j, -30.50244642 -56.21303872j,
       -57.93543536 -49.80593353j, 167.24328363+151.29814008j,
       -10.91586207 -66.24943608j, 273.43743482+274.69892934j])

观察快速傅里叶转换之后得到的结果:

  1. 转换的结果中,每个元素都是复数
  2. 前10个元素中,除去第一个,剩下的元素和后10个元素相比,实部相同,虚部相反

傅里叶变换之后,可以得到两个描述信号的图形:

  1. 频谱图:各个频率的波的振幅信息
  2. 相位图:各个频率的波的相位信息,相位就是波在特定时间所处的位置

频谱信息可以通过 np.abs 方法计算得出:

fig = plt.figure(figsize=[8,4])
ax1 = fig.add_subplot(121) 
data = np.abs(fft_result)
ax1.plot(data)
ax1.set_title("双边频谱图")

ax2 = fig.add_subplot(122) 
data = np.abs(fft_result[:50])
ax2.plot(data)
ax2.set_title("单边频谱图")

plt.show()

【scipy 基础】--傅里叶变换

相位信息可以通过 np.angle 方法计算得出:

fig = plt.figure(figsize=[8,4])
ax1 = fig.add_subplot(121) 
data = np.angle(fft_result)
ax1.plot(data)
ax1.set_title("双边相位图")

ax2 = fig.add_subplot(122) 
data = np.angle(fft_result[:50])
ax2.plot(data)
ax2.set_title("单边相位图")

plt.show()

【scipy 基础】--傅里叶变换

从这两个图中就能得变换后各个频率的信号的频率,振幅,相位信息。

2.2. 逆变换示例

逆变换就是将变换后的信号还原为原始信号。

因为傅里叶变换并没有任何信息的损失,所以逆变换之后可以看出信号的波形没有任何改变。

data = spfft.ifft(fft_result)

# 逆变换之后,忽略虚部的数字
plt.plot(x, np.real(data))
plt.show()

【scipy 基础】--傅里叶变换

3. 应用

最后,利用傅里叶变换,我们试着做一个改变声音效果的小例子。

首先,读取一段音频,Scipy就可以直接读取wav文件。

import scipy.io.wavfile as wav

# 读取音频,返回采样率和采样的数值
rate, all_samples = wav.read("/path/to/fft-test.wav")
print(rate)
print(all_samples[1000:1010])
# 运行结果
16000
[122 133 149 151 165 151 160 159 155 151]

plt.plot(all_samples)
plt.show()

【scipy 基础】--傅里叶变换
音频文件是网上随便找的一段英语对话。

接着,对读取的信号做傅里叶变换,观察变换后的结果:

dd = spfft.rfft(all_samples)
plt.plot(np.abs(dd))
plt.show()

【scipy 基础】--傅里叶变换
注意,这里用了 rfft函数,不是之前的fft函数,
两者的区别在于fft的结果是复数,会形成对称的双边图,就像上一节介绍的那样。
rfft的结果是实数,且是单边的,如上图所示。

这两个函数根据实际情况选择使用,都可以对信号进行傅里叶变换。
因为我后面的处理不需要双边的信息,所以这里用 rfft 函数来做傅里叶变换。

3.1. 处理一

第一种处理,我尝试把频率20000HZ以上的信号都去掉,看看音频的效果有什么变化。

new_data = dd.copy()
# 20000HZ以上频率的数据设为0
new_data[20000:] = 0

fig = plt.figure(figsize=[8,4])
ax1 = fig.add_subplot(121) 
ax1.plot(np.abs(new_data))

ax2 = fig.add_subplot(122) 
ax2.plot(np.abs(dd))

plt.show()

【scipy 基础】--傅里叶变换

处理之后的信号逆变换为原始信号,再保存为wav音频文件,看音频的变化效果。

new_data = spfft.irfft(new_data)
new_data = np.rint(new_data)
new_data = new_data.astype("int16")

wav.write("/path/to/fft-test-1.wav", rate, new_data) 

转换后的音频和原音频比,听起来声音更加闷一些,模糊一些。

3.2. 处理二

这次与处理一相反,把20000HZ以下的信号去掉。

new_data = dd.copy()
# new_data[20000:] = 0
new_data[:20000] = 0

fig = plt.figure(figsize=[8,4])
ax1 = fig.add_subplot(121) 
ax1.plot(np.abs(new_data))

ax2 = fig.add_subplot(122) 
ax2.plot(np.abs(dd))

plt.show()

【scipy 基础】--傅里叶变换

然后同样的把信号逆变换回去,并保存为wav文件。

new_data = spfft.irfft(new_data)
new_data = np.rint(new_data)
new_data = new_data.astype("int16")

wav.write("/path/to/fft-test-2.wav", rate, new_data) 

这次的声音听起来很遥远,像是长途电话的感觉。

4. 总结

本篇主要介绍了傅里叶变换是什么,以及如何使用Scipy库来进行傅里叶变换。
目的是了解和使用傅里叶变换,而不是从数学角度去推导傅里叶变换。

最后的小例子虽然简单,但见微知著,仅仅删除了一些频率的信号,声音效果就随之变化。
如果把不同声音的文件中,影响音调,音色的频率分析出来,就可以制作一个变声器,
把自己的声音变成男声女声,儿童老人等等。

进一步,用二维傅里叶变换的话,可以分析图像,把图像中的主要频率找出来,
深入下去既可以做图像修复,也可以做图像识别等等。

Scipy库中还有多维傅里叶变换,可以分析现实情况下更加复杂的信号。

5. 附录

文中用到的完整代码(ipynb格式)和一个音频文件,可以从下面的地址下载:
scipy-fft-sample.zip:
https://url11.ctfile.com/f/45455611-910542660-6d7e0f?p=6872
(访问密码: 6872)文章来源地址https://www.toymoban.com/news/detail-741284.html

到了这里,关于【scipy 基础】--傅里叶变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【高数+复变函数】傅里叶变换

    上一节 【高数+复变函数】傅里叶积分 回顾:上一节中主要讲了Fourier积分公式的指数形式及其三角形式 f ( t ) = 1 2 π ∫ − ∞ + ∞ [ ∫ − ∞ + ∞ f ( τ ) e − j ω τ d τ ] e j ω t d ω = 1 π ∫ 0 + ∞ [ ∫ − ∞ + ∞ f ( τ ) cos ⁡ ω ( t − τ ) d τ ] d ω f(t)=frac{1}{2pi}int_{-infty}^{+inf

    2024年02月04日
    浏览(35)
  • 图像的傅里叶变换

    先向大家道歉啊   作为基础知识这内容肯定有人写过   但作为屌丝没时间搜这个出处   也没什么商用价值 就是为了自己好看  收藏不好用 麻烦选别的   真的对不起就是为自己   烦请勿扰   看不惯你了 忍着 傅里叶基础 法国数学家吉恩·巴普提斯特·约瑟夫·傅里叶被

    2023年04月27日
    浏览(37)
  • 通俗讲解傅里叶变换

    参考:六一礼物:给孩子解释什么是傅里叶变换 牛!不看任何数学公式来讲解傅里叶变换  如何直观形象、生动有趣地给文科学生介绍傅里叶变换? - 知乎 从基说起…… 从数学的角度,提供一个形象有趣的解释。理解傅里叶变换的钥匙是理解基♂,它能让你重新认识世界。

    2024年02月09日
    浏览(25)
  • 傅里叶变换与Matlab

      很多初学者学习了傅里叶变换之后,只是对其公式死记硬背,从而达到做题的目的,但并不理解其原理,对于很多时频分析问题的理解不够透彻。之前自己也是如此,在经过深入学习之后,对变换公式的的本质进行探讨,理解变换的原理及意义所在,同时将傅里叶变换和

    2024年01月20日
    浏览(36)
  • 离散傅里叶变换(DFT)

    离散傅里叶变换(Discrete Fourier Transform)是信号分析中的一种基本方法,将离散时序信号从时间域变换到频率域,是傅里叶变换在时域和频域都呈离散的形式。 对于傅氏变换,其定义为: 利用该公式,可以实现对一些符合条件的连续函数进行傅氏变换。然而,在很多时候,我们

    2024年02月11日
    浏览(25)
  • Matlab:二维傅里叶变换

    fft2 函数将二维数据变换为频率空间。例如,您可以变换二维光学掩膜以揭示其衍射模式。 以下公式定义 m×n 矩阵 X 的离散傅里叶变换 Y。 i 是虚数单位,p 和 j 是值范围从 0 到 m–1 的索引,q 和 k 是值范围从 0 到 n–1 的索引。在此公式中,X 和 Y 的索引平移 1 位,以反映 M

    2023年04月17日
    浏览(29)
  • 快速傅里叶变换——FFT

    1·为什么要进行傅里叶变换 傅里叶变换——进行信号的分解过程 时域信号——分解成一系列频率下的正弦//余弦信号(两者在相位上有所不同),一般情况下可以统称为正弦信号。  上图表示了傅里叶的变化过程。对于时域的信号,可以将其分解成一系列频域下的正弦信号,

    2024年02月10日
    浏览(33)
  • 深入理解傅里叶变换(一)

    三棱镜能将太阳光分解成七种颜色的可见光。我们知道这七种颜色有不同的波长范围,从而对应不同的频率范围。这给我们一个启示:太阳光这种看起来是白色的光,其实是由不同频率的光组成的,而三棱镜能起到将太阳光分解成不同频率的光的作用。 如果把三棱镜看作是一

    2024年02月02日
    浏览(67)
  • matlab快速傅里叶变换

    快速傅里叶变换(FFT)是数字信号处理中常用的算法之一,可以用于信号分析、滤波、频率估计和信号生成等。在 Matlab 中,快速傅里叶变换是一个重要的工具,可以快速地计算信号的频域表示,帮助研究人员更好地理解和分析信号。本文将介绍 Matlab 中的快速傅里叶变换及其

    2024年02月09日
    浏览(31)
  • opencv4 傅里叶变换

    ① 高频:变化剧烈的灰度分量,例如边界礁石。 ② 低频:变化缓慢的灰度分量,例如一片大海。 ③ 高通滤波器:只保留高频,会使得图像细节增强。高频边界锐化了,增强了,细节更明显了。 ④ 低通滤波器:只保留低频,会使得图像模糊。低频信息保留下来了,高频信息

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包