文章目录

  • 傅里叶变换的更多性质
    • 能量不变(Energy conservation)
    • 分贝幅度(Amplitude in decibels(dB))
    • 相位展开(Phase unwrapping)
    • 补零(Zero-padding)
    • 快速傅里叶变换(FFT)
    • 零相位窗(Zero-phase windowing)
  • 总结

傅里叶变换的更多性质

除了上一篇博文傅里叶变换的基本性质所提到的性质外,傅里叶变换还有一些非常有用的性质和概念,包括:

  • 能量不变(Energy conservation)
  • 分贝幅度(Amplitude in decibels(dB))
  • 相位展开(Phase unwrapping)
  • 补零(Zero-padding)
  • 快速傅里叶变换(FFT)
  • 零相位窗(Zero-phase windowing)

以上概念或者性质能够帮助我们更好利用傅里叶变换对信号进行分析,接下来配合具体代码逐个说明

首先导入必要的库

import numpy as np
from scipy.fftpack import fft
from scipy.io.wavfile import read as WAV_read
from scipy.signal import get_window
import matplotlib.pyplot as plt
%matplotlib inline

能量不变(Energy conservation)

即在时域上计算能量的结果与在频域上的结算结果不变,公式表达为:
∑n=−N/2N/2−1∣x[n]2∣=1N∑k=−N/2N/2−1∣X[k]2∣\sum_{n=-N/2}^{N/2 - 1}\vert x[n]^2\vert = \frac{1}{N}\sum_{k=-N/2}^{N/2 - 1} \vert X[k]^2\vert n=−N/2∑N/2−1​∣x[n]2∣=N1​k=−N/2∑N/2−1​∣X[k]2∣

我们举个小例子来说明这个性质

下面的代码计算了一段信号在时域和频域上的信号,结果显示,它们完全一致

N = 511
audio_path = 'sounds/soprano-E4.wav'
(fs, x) = WAV_read(audio_path)
x = x[1000:1000+N]
w = get_window('blackman', N)
xw = x*w;
plt.plot(xw)
plt.show()X = fft(xw)# calculating energy in time domain and frequency domain
energy_in_time = np.sum(np.square(xw))
energy_in_freq = 1.0/N * np.sum(np.square(np.abs(X)))print('Energy in time domian :', energy_in_time)
print('Energy in frequency domian :', energy_in_freq)

Energy in time domian : 113106768.166
Energy in frequency domian : 113106768.166

分贝幅度(Amplitude in decibels(dB))

通过对幅度进行对数,可以得到分贝幅度。分贝幅度视觉效果更好,具体计算公式为:
A=20∗log⁡(abs(X))A = 20*\log(abs(X)) A=20∗log(abs(X))

其中A表示分贝幅度,X为傅里叶变换后的信号,log⁡\loglog是以10为底的对数操作

分贝幅度能够更好显示幅度的变化

下面的程序演示了分贝幅度的计算过程

N = 1024
audio_path = 'sounds/soprano-E4.wav'
(fs, x) = WAV_read(audio_path)
x = x[1000:1000+N]
w = get_window('blackman', N)
xw = x*wX = fft(xw)
abs_X = np.abs(X)
mX = 20*np.log10(abs_X)plt.figure(figsize=(12,10))plt.subplot(311)
plt.plot(xw);plt.title('x')plt.subplot(312)
plt.plot(abs_X);plt.title('abs(X)')plt.subplot(313)
plt.plot(mX);plt.title('20*log10(abs(X))')plt.show()

相位展开(Phase unwrapping)

幅度可以用分贝幅度来获得更好的表示,同样的,相位能够用相位展开来优化显示效果

如果不使用相位展开,相位会严格的落在[π,−π][\pi, -\pi][π,−π]之间,这样显示的相位看起来特别乱,没有规律

关于相位展开的详细说明,请参看Unwrap
根据上面这个参考链接,我们可以写一个自己的简单版本的unwrap

下面代码说明如何做相位展开以及如何写unwrap

def my_unwrap(p):discont = np.piunwraped_p = np.zeros(p.size)unwraped_p[0] = p[0]count = 0# 遍历相位,下标从1开始for i in range(1, len(p)):diff = p[i] - p[i-1]if(diff > discont):count -= 2elif(diff < -discont):count += 2unwraped_p[i] = p[i] + count*np.pireturn unwraped_p
N = 511
audio_path = 'sounds/soprano-E4.wav'
(fs, x) = WAV_read(audio_path)
x = x[1000:1000+N]
w = get_window('blackman', N)
xw = x*wX = fft(xw)
abs_X = np.abs(X)
mX = 20*np.log10(abs_X)
px1 = np.angle(X)
px2 = np.unwrap(px1)
px3 = my_unwrap(px1)plt.figure(figsize=(12,15))plt.subplot(411)
plt.plot(xw);plt.title('x')plt.subplot(412)
plt.plot(px1);plt.title('px1 = phase spectrum')plt.subplot(413)
plt.plot(px2);plt.title('px2 = unwrapped phase specturm')plt.subplot(414)
plt.plot(px3);plt.title('px3 = unwrapped phase specturm by using my_unwrap')plt.show()

补零(Zero-padding)

在时域信号上的尾部补零,那么等同于在频域上做插值

补零是非常有用的一个性质,它可以增加频域的分辨率

x = np.array([0,0,-.5,0,1,0.5,0,0])
X = fft(x)
mX1 = np.abs(X)# 在x尾部添加了8个0
x2 = np.pad(x, (0,8), 'constant', constant_values=(0))
X2 = fft(x2)
mX2 = np.abs(X2)# 在x1尾部添加了16个0
x3 = np.pad(x2, (0,16), 'constant', constant_values=(0))
X3 = fft(x3)
mX3 = np.abs(X3)plt.figure(figsize=(12,15))plt.subplot(411)
plt.plot(x);plt.title('x')plt.subplot(412)
plt.plot(mX1);plt.title('magnitude spectrum: mX1, N=8')plt.subplot(413)
plt.plot(mX2);plt.title('magnitude spectrum: mX2, N=16')plt.subplot(414)
plt.plot(mX3);plt.title('magnitude spectrum: mX3, N=32')plt.show()

快速傅里叶变换(FFT)

快速傅里叶变换由Cooley-Tukey提出,将傅里叶变换的计算复杂度从O(n^2)减低到O(nlogn),但是算法要求输入数据的长度必须是2的次幂

因此,为了使用FFT,我们通常需要对输入信号进行补零至2的次幂大小

另外要说的就是Scipy中的fft,如果输入大小为2的次幂大小,那么fft做快速傅里叶变换,否则它做离散傅里叶变换

通常,在信号处理中,我们都使用FFT,因为它快啊

零相位窗(Zero-phase windowing)

在使用FFT时,除了要补零以外,通常还要加一个零相位窗的操作,所谓零相位就是让信号以第0个抽样点左右对称。参看零相位,线性相位与非线性相位

这么做的好处:得到的结果具有对称性,非常棒

零相位窗的操作很简单,请看下面的示意图

配合代码,你肯定能明白零相位窗是怎么工作的

M = 411
audio_path = 'sounds/soprano-E4.wav'
(fs, x) = WAV_read(audio_path)
x = x[1000:1000+M]
w = get_window('blackman', M)
w = w/sum(w)
xw = x*wN = 1024 # power of 2
fftbuffer = np.zeros(N)
hm1 = (M+1)//2
hm2 = M//2
fftbuffer[:hm1] = xw[-hm1:]
fftbuffer[-hm2:] = xw[:hm2]X = fft(fftbuffer)
mX = 20*np.log10(np.abs(X))
pX = np.unwrap(np.angle(X))plt.figure(figsize=(12,15))plt.subplot(411)
plt.plot(xw);plt.title('x: M = 411')plt.subplot(412)
plt.plot(fftbuffer);plt.title('fftbuffer: N=1024')plt.subplot(413)
plt.plot(mX);plt.title('mX')plt.subplot(414)
plt.plot(pX);plt.title('pX')plt.show()

总结

以上我们总结了傅里叶变换常用的性质和概念,讲清楚了这些,在下一个文章中,我们就可以实现一个完整的DFT代码啦

傅里叶变换的更多性质:相位展开、零相位窗等相关推荐

  1. PMD相位提取及相位展开简述

    1.相位提取 相位提取又分为好多种方法,但目前最常用的是相移法,利用相移法进行相位提取相移步数最少为3步,综合速度以及抗干扰使用4相移,相移步数越多可减少非线性噪声干扰,但提取速度会变慢,可利用12步 ...

  2. matlab进行相位展开,相位展开(phase unwrapping)算法研究与实践

    1. 什么是相位展开? 相位展开(Phase Unwrapping)是一个经典的信号处理问题,它指的是从值区间 中恢复原始相位值(原因在于:计算相位时,运用反正切函数,则相位图中提取的相位都是包裹在一 ...

  3. 地震信号-相关子波零相位化

    本文首发于 算法社区 dspstack.com,转载请注明出处,谢谢. 初衷:这几天写了两篇关于地震信号的文章,是由于社区有个小伙伴在提问,所以以答疑为契机,写了这两篇:之后看时间安排还会继续的 前言 ...

  4. 零相位滤波matlab,什么叫零相位滤波器(最小相位滤波器)

    本文主要介绍什么是阶段,阶段给了我们什么启示?什么是相位滤波,相位滤波在整个声音系统中起着什么重要的作用.在本文的最后,我们将通过一个典型的相位滤波调试案例,与朋友们分享分频系统中相位均衡调试的重要性 ...

  5. IIR+全通滤波器级联实现系统零相位相移_matlab仿真

    1.前言 前面详细的介绍了如何通过优化的思想逆向设计符合要求的全通相位平衡系统!实际上,线性相位的要求要比零相位相移的要求苛刻的多. 晚上和好友解释了一下如何利用优化思想实现线性相位,好友感觉很难实现 ...

  6. IIR+双向滤波实现系统零相位相移_MATLAB仿真

    1.双向滤波实现零相移的思想 Matlab软件有一个m文件filtfilt.m,可以实现零相位数字滤波.它先将输入序列按顺序滤波(forward filter),然后将所得结果逆转后反向通过滤波器(r ...

  7. 带通滤波中零相位和最小相位_相位器在Perl 6中的工作方式

    带通滤波中零相位和最小相位 这是关于将代码从Perl 5迁移到Perl 6 的系列文章中的第六篇 .本文着眼于Perl 5中的特殊块 ,例如BEGIN和END ,以及Perl中所谓的相位器在语义上的细 ...

  8. 相位展开(phase unwrapping)

    我在做科研项目时,遇到过使用相位信息,但是相位被折叠(wrapped)的情况,相位计算公式如下: Θ = a r c t a n ( b a ) \Theta = arctan(\frac{b}{a} ...

  9. MATLAB零相位数字滤波 filtfilt

    % 零相位数字滤波 n = 1:1:512; x = 3* sin(2*pi*133*n/10000) + cos(2*pi*2333*n/10000); [B A]=cheby1(5,0.2,0.1 ...

最新文章

  1. 让机器听懂人话的自然语言处理技术究竟神奇在哪里?
  2. Fedora 快捷键
  3. antd 表单域验证规则 - 只能输入数字字符,去除前导0
  4. 业务逻辑数据层SqlDataSourcesql的输入参数控件参数System.Web.UI.WebControls.GridView.SelectedValue...
  5. 现在开始全职跑滴滴,你怎么看?
  6. socket.io简介
  7. 元胞计算机系统,元胞自动机
  8. Firefox上打开的标签页太多怎么办?
  9. android gps信号一直获取不到_抵押车的GPS到底能不能拆干净!
  10. oracle10g rac导出ocr,Oracle RAC OCR磁盘故障快速恢复方法
  11. 1047: 对数表 Python
  12. 2022淘宝618超级喵运会怎么玩?2022淘宝618喵运会玩法技巧
  13. 给html标签加上鼠标划过小手样式
  14. 最新WingIDE注册破解方法
  15. labview与PLC通讯
  16. 智能语音技术的深度解析
  17. 群晖QuickConnect与DDNS之间有何区别?
  18. Linux:安装和配置tomcat详细教程
  19. Linux系统结构与虚拟机使用
  20. [Hive优化]--常用参数优化汇总

热门文章

  1. java五子棋棋盘_java五子棋项目(一)
  2. harbor安装_Harbor任意管理员注册漏洞(CVE-2019-1609) (附:批量利用poc)
  3. 无线打印机 连接路由器连接到服务器,怎么通过无线路由器连到有的打印机线网络...
  4. html调用js函数_使用Require.js实现模块化开发
  5. idea java opts_idea为java程序添加启动参数(program arguments,vm arguments,Environment variable),并在程序中获取使用...
  6. wpf tabitem 点击事件_Mindfusion教程:WPF中的Fishbone(Ishikawa)图
  7. 基于Python的接口自动化unittest测试框架和ddt数据驱动详解
  8. edittext 无法输入内容_掌握其中1个Excel小技巧,你就不用再担心会重复录入内容了。...
  9. spring cloud全家桶_吃透这份Github点赞120k的Spring全家桶笔记Offer拿到手软
  10. JS有哪些数据类型?