python 数字信号产生并求其FFT

python 数字信号产生并求其FFT

本文写了一篇关于数字信号发生和做FFT处理的文章。

信号产生模块

这个模块用于产生单位阶跃信号、单位脉冲信号、简单的锯齿波信号。

也就是常用的数字信号处理中常用的序列。
话不多说,直接上代码:

signal_module.py:

import numpy as np

def saw_tooth(n0,n1,n2):
	# Generates x(n)=saw_tooth
	# -----------------------------------------
	# n,x = saw_tooth(n0, n1, n2)  n1 <= n0, n0 <= n2
	num=0
	if (n0<n1 or n2<n1 or n2<n0):
		raise Exception('arguments must satisfy n1<=n0<=n2')
	else:
		n=np.arange(n1,n2+1)
		x=np.zeros(len(n))
		no = np.arange(len(n))
		for a in no:
			if a < n0-n1:
				x[a]=0
			else:
				x[a]=num
				num+=1
	return n,x

def step_seq(n0,n1,n2):
	# Generates
	# x(n) = u(n - n0);
	# n1 <= n0, n0 <= n2
	if (n0<n1) or (n2<n1) or (n2<n0):
		raise Exception('arguments must satisfy n1<=n0<=n2')
	else:
		n=np.arange(n1,n2+1)
		x=(n>=n0)*1.
	return n,x

def imp_seq(n0,n1,n2):
	# Generates x(n)=delta(n-n0);n1<=n0,n0<=n2
	# -----------------------------------------
	# [x, n] = impseq(n0, n1, n2)
	if (n0<n1) or (n2<n1) or (n2<n0):
		raise Exception('arguments must satisfy n1<=n0<=n2')
	else:
		n=np.arange(n1,n2+1)
		x=(n==n0)*1.
	return n,x

if __name__ =="__main__":
	from matplotlib import pyplot as plt
	n1,x1=saw_tooth(5,1,10)
	n2,x2=imp_seq(5,1,10)
	n3,x3=step_seq(5,1,10)
	plt.subplot(3, 1, 1)
	plt.stem(n1, x1, use_line_collection=True)
	plt.title("sawtooth")
	plt.xlabel("n")
	plt.subplot(3, 1, 2)
	plt.stem(n2, x2, use_line_collection=True)
	plt.title("impseq")
	plt.xlabel("n")
	plt.subplot(3, 1, 3)
	plt.stem(n3, x3, use_line_collection=True)
	plt.title("stepseq")
	plt.xlabel("n")
	plt.show()

运行结果:

image-20210602144616559

快速傅里叶变换

这里参考了:https://blog.csdn.net/qq_27825451/article/details/88553441

import numpy as np
from scipy.fftpack import fft, ifft
import matplotlib.pyplot as plt
from matplotlib.pylab import mpl
from signal_module import *

mpl.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
mpl.rcParams['axes.unicode_minus'] = False  # 显示负号

n, y1 = imp_seq(40, 0, 99)
n, y2 = imp_seq(50, 0, 99)
n, y3 = imp_seq(60, 0, 99)
n, y4 = imp_seq(70, 0, 99)
y=y1+y2+y3+y4                 #4个序列相加
fft_y = fft(y)  # 快速傅里叶变换

N = 100
x = np.arange(N)  # 频率个数
half_x = x[range(int(N / 2))]  # 取一半区间

abs_y = np.abs(fft_y)  # 取复数的绝对值,即复数的模(双边频谱)
angle_y = np.angle(fft_y)  # 取复数的角度
normalization_y = abs_y / N  # 归一化处理(双边频谱)
normalization_half_y = normalization_y[range(int(N / 2))]  # 由于对称性,只取一半区间(单边频谱)

plt.subplot(231)
plt.plot(n, y)
plt.title('原始波形')

plt.subplot(232)
plt.plot(x, fft_y, 'black')
plt.title('双边振幅谱(未求振幅绝对值)', fontsize=9, color='black')

plt.subplot(233)
plt.plot(x, abs_y, 'r')
plt.title('双边振幅谱(未归一化)', fontsize=9, color='red')

plt.subplot(234)
plt.plot(x, angle_y, 'violet')
plt.title('双边相位谱(未归一化)', fontsize=9, color='violet')

plt.subplot(235)
plt.plot(x, normalization_y, 'g')
plt.title('双边振幅谱(归一化)', fontsize=9, color='green')

plt.subplot(236)
plt.plot(half_x, normalization_half_y, 'blue')
plt.title('单边振幅谱(归一化)', fontsize=9, color='blue')

plt.show()

运行结果:

image-20210602151615235
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值