【python数字信号处理】——DFT、DTFT(频谱图、幅度图、相位图)
目录
参考:
一、离散时间傅里叶变换DTFT
时间序列变量范围(-∞,+∞)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/20 17:56
# @Author : @linlianqin
# @Site :
# @File : DTFT.py
# @Software: PyCharm
# @description:https://blog.csdn.net/weixin_42193451/article/details/122384485
import math
import numpy as np
# 三角函数sin(nπ)的DTFT
class dtft():
def __init__(self,xvalues:list):
'''
:param xvalues: 时域自变量t序列
'''
self.yvalues = []
self.xvalues = xvalues
def xjw(self,fre:list):
'''
:param fre: 频率自变量fre序列
:return:
'''
# 实现yvalues为X(jw)频谱值
## 遍历频率自变量
for f in fre:
p = 0
# 遍历时间序列,得到累加和
for x in self.xvalues:
p = math.sin(x*np.pi)*math.e**(-1j*f*x) + p
self.yvalues.append(p) # 对应每一个自变量频率的因变量值
if __name__ == '__main__':
import numpy as np
from matplotlib import pyplot as plt
xvalues = np.arange(-2,2,0.1)
y1 = [np.sin(i*np.pi) for i in xvalues]
# 原信号sin(nπ)
plt.subplot(221)
plt.plot(xvalues,y1)
# 频谱
DTFT = dtft(xvalues)
freOmega = np.arange(0,20,0.01)
DTFT.xjw(freOmega)
plt.subplot(222)
plt.plot(freOmega,DTFT.yvalues)
# 幅度谱
plt.subplot(223)
plt.plot(freOmega,np.abs(DTFT.yvalues))
# 相位谱
plt.subplot(224)
angle_ = np.angle(DTFT.yvalues)/np.pi
plt.plot(freOmega,180*angle_)
plt.show()
二、离散傅里叶变换DFT
时间序列变量n为离散取值(0,N),即0,1,2,3…,N
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/20 17:57
# @Author : @linlianqin
# @Site :
# @File : DFT.py
# @Software: PyCharm
# @description:https://blog.csdn.net/weixin_42193451/article/details/122384485
import math
import numpy as np
class dft():
def __init__(self,Num):
'''
:param Num: dft点数,即离散取样点数
'''
super().__init__()
self.Num = Num
self.xk = [] # 存放dft计算结果
self.K = list(range(0,self.Num,1)) # 时域序列横坐标,采样
def Xk(self):
# 计算频域中的频率自变量值
W = []
for x in self.K:
W.append(x*2*math.pi/len(self.K))
## 遍历频率自变量
for f in W:
p = 0
# 遍历时间序列,得到累加和
for k in self.K:
p = math.sin(k*np.pi)*math.e**(-1j*f*k) + p
self.xk.append(p) # 对应每一个自变量频率的因变量值
if __name__ == '__main__':
import numpy as np
from matplotlib import pyplot as plt
xvalues = np.arange(-2,2,0.1)
y1 = [np.sin(i*np.pi) for i in xvalues]
# 原信号sin(nπ)
plt.subplot(221)
plt.plot(xvalues,y1)
# 频谱
N = 16 # 采样点数
DFT = dft(N)
DFT.Xk()
plt.subplot(222)
plt.plot(DFT.K,DFT.xk)
# 幅度谱
plt.subplot(223)
plt.stem(DFT.K,np.abs(DFT.xk))
# 相位谱
plt.subplot(224)
angle_ = np.angle(DFT.xk)
plt.stem(DFT.K,180*angle_/np.pi)
plt.show()
三、DFT与DTFT的关系
DTFT.py
import math
import numpy as np
class dtft():
#xvalues:输入序列
def __init__(self,xvalues=[]):
self.yvalues = []
self.xvalues = xvalues
#fre:频率坐标
def xjw(self,fre = []):
#(式1-1)实现yvalues为X(jw)频谱值
for f in fre:
p = 0;
for x in self.xvalues:
p = math.e**(-1j*f*x) + p
self.yvalues.append(p)
DFT.py
from DTFT import dtft
import math
class dft(dtft):
#Num:dft点数,self.Num序列值,self.K 序列横坐标,self.xk:存放dft计算结果,
#self.Xk():式(3-1)计算dft
def __init__(self,Num,xvalues):
super().__init__(xvalues)
self.Num = Num
self.xk = []
self.K = list(range(0,self.Num,1))
self.Xk()
def Xk(self):
W = []
for x in self.K:
W.append(x*2*math.pi/len(self.K))
self.xjw(W)
for x in self.yvalues:
self.xk.append(abs(x))
使用方法和一、二一样,只是这里的DFT算法的编写是继承了DTFT类,便于理解二者的关系