使用Python进行信号处理(1)信号简介与常见信号

目录

准备工作

作出第一个信号

连续信号与离散信号

模拟信号与数字信号

利用Python绘制常见信号

方波信号

三角波信号

复指数信号

抽样信号


最近正在学习信号处理,可以利用Python更加直观地感受信号的变化。

准备工作

Python通过其丰富的库和框架为信号处理提供了强大的支持,使用python进行信号处理需要三个包:Numpy , Matplotlib , Scipy 

在命令行中:

使用以下命令安装Numpy,主要用于数据的产生与组织

pip install numpy

使用以下命令安装Matplotlib,主要使用其中的pyplot模块进行信号的可视化

pip install matplotlib

使用以下命令安装Scipy,主要利用其signal模块进行信号处理和各种变换

pip install scipy

作出第一个信号

先拿最简单的正弦信号练练手:

作出下面正弦信号的图像

y(t)=sin(2\pi f t)\ \ \ \ \ f=10Hz\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (t\in [0,1])

程序代码如下:

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt

f=10    #频率定为10Hz
t=np.linspace(0 , 1 , 500)    #范围从0-1,等间隔取500个点
y=np.sin( 2*np.pi*f * t)    #此处的y也是500个点,与t的值一一对应

plt.figure(figsize=(10,4))    #创建一张10×4大小的图像
plt.plot(t,y)   #作出曲线

plt.show()    #注意:一定要有这行代码,否则图像不会显示!

得到信号图像:

下面简单解释一下代码:

t=np.linspace(0 , 1 , 500)

np.linspace(start,stop,num) 用于创建均匀间隔的一维序列,可以传入三个参数:依次为起始值,终止值,点的数量,得到的序列默认是包含起始值和终止值的。此处创建了范围在0-1之间等距的500个值组成的序列。

plt.figure(figsize=(10,4))    

plt.figure( ) 创建一个图像,可以理解为一张空白的画布,其中的参数 figsize 可以控制画布的大小。在信号处理中,信号的时域波形和频谱的长宽比较大。此处创建了10×4大小的图像。这行代码下面的命令都是在这张画布的基础上进行绘图。

plt.plot(t,y)

plt.plot(a,b) 作出b关于a变化的图像,a和b是相同长度np.ndarray对象,可由 np.linspace( ) 创建。此时a为自变量,b为因变量,该函数会将相邻的(a,b)点(横坐标为a中的值,纵坐标为b中对应的值)之间用直线相连。为了得到看上去平滑的曲线,需要减少相邻点的距离,即增加参与作图的点的个数,因此前面横坐标在0和1之间取了500个点。

连续信号与离散信号

信号可以分为连续信号和离散信号,连续信号在相应的时间区间内处处有值,且信号强度随着时间变化而连续变化,而离散信号只在特定的某些时间点有值。上面所作的正弦信号即为连续信号。

通常,作连续信号的图像时使用plt.plot命令将每个时间点对应的信号值相连,时间点越密集,曲线越平滑。同样的正弦信号在同样的时间区间内,下图是仅取100个时间点使用plt.plot命令后的效果:

可以看到出现了很多尖锐且不连续的部分。

离散时间信号的图像常用plt.stem命令,该命令会将各时间点的信号强度作为一个孤立的点进行绘制。例如,绘制信号

y(t)=sin(2\pi f n)\ \ \ \ \ f=0.1Hz\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (n\in [0,10],n\in Z)

的图像,可采用以下代码:

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt

f=0.1
t=np.linspace(0 , 10 , 11)  #在0-10中均匀取11个点,即0,1,2...10
y=np.sin( 2*np.pi*f * t)
plt.figure(figsize=(10,4))    #创建一张10×4大小的图像
plt.stem(t,y)   #作出离散信号图像

plt.show()
print(type(t))

作出的图像如图:

模拟信号与数字信号

若将离散时间信号在各个时间点上的信号幅值也取离散值,就形成了数字信号,数字信号具有易于传输、抗干扰能力强等特点;与之相反,在时间和幅值上都是连续的时间信号有时也称为模拟信号,自然界中的信号均为模拟信号。

利用Python绘制常见信号

接下来介绍一些常见信号在python中的绘制方法,同时穿插一些常见的画图函数的用法。

方波信号

在python中,可以利用Scipy中的signal模块中的square函数绘制方波。其用法如下:

singnal.square(t,duty=0.5) 传入两个参数,第一个是时间序列,是np.ndarray对象,第二个参数是占空比,默认为0.5,即50%。要注意的是,该函数产生的方波默认周期为2\pi0-\pi上值为1,\pi -2\pi值为-1。若想自己定周期或者频率,比如要想绘制[0,1]上频率为2Hz(即周期为0.5s)的方波,需要使用以下代码

t=np.linspace(0,1,500)    #在0-1上取500个点,即信号所在时间序列
f=2
y=signal.square(2*np.pi*f*t)    #在时间序列前乘上2*pi*f,是为了获得想要的频率

此代码绘制出的方波信号周期变为2\pi除以信号所处的时间序列前面的系数,在 x \in [0,\frac{\pi }{2\pi f} ] 时,函数值为1,在 x \in [\frac{\pi }{2 \pi f},\frac{2 \pi}{2 \pi f}] 时,函数值为-1,即以\frac{2 \pi}{2 \pi f}= \frac{1}{f} =0.5s为周期,前半周期为1,后半周期为-1。

完整代码如下:

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

#方波信号
t=np.linspace(0,1,500)
f=2                                       #2Hz
y=signal.square( 2*np.pi*f*t,duty=0.5)    #占空比为0.5的方波信号
plt.figure(figsize=(8,4))
plt.plot(t,y)

plt.show()

作出的方波如图所示

三角波信号

在python中,可以利用Scipy中的signal模块中的sawtooth函数绘制三角波。其用法如下:

signal.sawtooth(t,width), 第一个参数square函数相同,第二个参数指的是三角波的上升部分时间占一个周期的比例,取值范围为[0,1],默认为1,即在一整个周期都处于上升状态。若取值为0.5,则一个周期的前半部分上升,后半部分下降,此时,上升部分和下降部分所占时间相同。三角波周期和频率的计算与方波类似。比如,在[0,1]上作出频率为5Hz的三角波图像。width值分别取0.5和1,代码如下:

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

#三角波信号
t=np.linspace(0,1,500)
f=5                                         #5Hz
y1=signal.sawtooth( 2*np.pi*f*t,width=0.5)  #周期为2*pi/(2*pi*f) = 1/f
y2=signal.sawtooth( 2*np.pi*f*t,width=1)
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)                          #第一幅图
plt.plot(t,y1)
plt.title('width=0.5,f=5Hz')                #添加标题

plt.subplot(1,2,2)                          #第二幅图
plt.plot(t,y2)
plt.title('width=1,f=5Hz')                  #添加标题

plt.show()

作出结果如下:

下面简单解释一下其中用到的部分作图函数

plt.subplot(1,2,1)

plt.subplot(raw,column,num)可将画布分成raw行,column列,共raw×column个分画布,并在第1个分画布上绘图,其序号从左往右,从上往下依次增大。这行代码就是将原来的大画布分成了一行两列,并在第一个(即左侧)子画布上绘图。

plt.title('width=0.5,f=5Hz')

plt.title(text)顾名思义,给当前画布起个标题。

复指数信号

复指数信号是形如f(t)=Ke^{st}的信号,其中s=\sigma + j\omega,利用欧拉公式可将该信号分解如下:

Ke^{(\sigma+j\omega)t} = Ke^{\sigma t}cos \omega t\ +j Ke^{\sigma t}sin\omega t

此时,该信号的实部与虚部分别包含了余弦信号和正弦信号,且都乘上了一个指数律变化的因子。复指数信号在现实中无法实现,但其包含了很多常见的信号。以其实部为例,利用以下代码对比不同的\sigma\omega值对信号f(t)=Ke^{\sigma t}cos \omega t的影响

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt

t=np.linspace(0,5,500)
sigma1=1                #不同的参数值
sigma2=0
sigma3=-1
omega1=4*np.pi
omega2=0
K=1

plt.figure(figsize=(9,9))
y1=np.exp(sigma1*t)*np.cos(omega1*t)
y2=np.exp(sigma2*t)*np.cos(omega1*t)
y3=np.exp(sigma3*t)*np.cos(omega1*t)
y4=np.exp(sigma1*t)*np.cos(omega2*t)

plt.subplot(2,2,1)      #分成4张子图
plt.plot(t,y1)
plt.title('$\sigma = 1,\omega = 4\pi$')
plt.subplot(2,2,2)
plt.plot(t,y2)
plt.title('$\sigma = 0,\omega = 4\pi$')
plt.subplot(2,2,3)
plt.plot(t,y3)
plt.title('$\sigma = -1,\omega = 4\pi$')
plt.subplot(2,2,4)
plt.plot(t,y4)
plt.title('$\sigma = 1,\omega = 0$')

plt.show()

得到图像:

由图及理论计算可知:

\sigma \textgreater 0,\omega \neq0时,为增幅正弦信号

\sigma =0,\omega \neq0时,为等幅正弦信号

\sigma <0,\omega \neq0时,为减幅正弦信号

\sigma \neq 0,\omega =0时,为指数信号

显然,当\sigma =0,\omega =0时,为直流信号

抽样信号

我们把形如f(t)=\frac{sint}{t}的信号称为抽样信号,记为Sa(t),该信号在之后会经常用到。在python中可以利用辛格函数sinc(t)=\frac{sin(\pi t)}{\pi t}产生抽样信号,使用np.sinc()进行绘制,代码如下:

#导入所需的包
import numpy as np
import matplotlib.pyplot as plt

#抽样信号
t=np.linspace(-5*np.pi,5*np.pi,500)
y=np.sinc(t/np.pi)
plt.figure()


plt.plot(t,y)

plt.show()

作出的图像:

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值