SciPy科学计算与应用:SciPy信号处理入门-从理论到实践

发布于:2025-08-29 ⋅ 阅读:(19) ⋅ 点赞:(0)

信号处理:SciPy入门实践

学习目标

通过本课程,学员将掌握如何使用SciPy的信号处理模块(scipy.signal)进行基本的信号处理操作,包括滤波、卷积和傅里叶变换。同时实验将通过理论讲解与实践操作相结合的方式,帮助学员掌握信号处理的基本技能。

相关知识点

  • 信号处理:SciPy入门实践

学习内容

1 信号处理:SciPy入门实践

1.1 滤波器设计与应用

滤波器是信号处理中非常重要的工具,用于从信号中去除不需要的频率成分或增强某些频率成分。在数字信号处理中,滤波器的设计和应用是通过数字滤波器实现的。数字滤波器可以分为两大类:无限脉冲响应(IIR)滤波器和有限脉冲响应(FIR)滤波器。IIR滤波器的特点是具有反馈路径,可以实现非常陡峭的过渡带,但可能会引入相位失真。FIR滤波器则没有反馈路径,相位响应更加线性,但通常需要更多的计算资源。

在SciPy中,scipy.signal模块提供了丰富的函数来设计和应用这两种类型的滤波器。下面,将通过一个简单的例子来学习如何使用SciPy设计一个低通滤波器,并将其应用于一个模拟信号。

1.1.1 设计低通滤波器

首先,需要设计一个低通滤波器。低通滤波器允许低于截止频率的信号通过,而高于截止频率的信号则被衰减。在SciPy中,可以使用butter函数来设计一个巴特沃斯滤波器,这是一种常见的IIR滤波器。

from scipy.signal import butter, lfilter

def butter_lowpass(cutoff, fs, order=5):
    nyq = 0.5 * fs  # Nyquist Frequency
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return b, a

def butter_lowpass_filter(data, cutoff, fs, order=5):
    b, a = butter_lowpass(cutoff, fs, order=order)
    y = lfilter(b, a, data)
    return y

# 参数设置
order = 6
fs = 30.0       # sample rate, Hz
cutoff = 3.667  # desired cutoff frequency of the filter, Hz

# 生成测试信号
import numpy as np
T = 5.0         # seconds
n = int(T * fs) # total number of samples
t = np.linspace(0, T, n, endpoint=False)
# "Noisy" data.  We want to recover the 1.2 Hz signal from this.
data = np.sin(1.2*2*np.pi*t) + 1.5*np.cos(9*2*np.pi*t) + 0.5*np.sin(12.0*2*np.pi*t)

# 应用滤波器
y = butter_lowpass_filter(data, cutoff, fs, order)

# 绘制结果
import matplotlib.pyplot as plt
plt.plot(t, data, 'b-', label='data')
plt.plot(t, y, 'g-', linewidth=2, label='filtered data')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

这段代码首先定义了两个函数:butter_lowpass用于设计低通滤波器,butter_lowpass_filter用于应用滤波器。然后生成了一个包含多个频率成分的测试信号,并应用了低通滤波器。最后使用Matplotlib绘制了原始信号和滤波后的信号,以直观地展示滤波效果。

1.2 卷积操作

卷积是信号处理中的另一个基本操作,用于分析信号的特征或与其他信号进行交互。在数学上,卷积是两个函数(信号)的线性运算,结果是一个新的函数,表示一个函数在另一个函数上的加权平均。在数字信号处理中,卷积通常用于实现滤波器、信号平滑等操作。

在SciPy中,scipy.signal模块提供了convolve函数来执行卷积操作。下面将通过一个简单的例子来学习如何使用SciPy进行卷积操作。

1.2.1 卷积操作示例

假设有一个简单的信号和一个卷积核,希望使用卷积操作来平滑这个信号。

from scipy.signal import convolve

# 生成一个简单的信号
signal = np.sin(2 * np.pi * t) + 0.5 * np.random.randn(n)

# 定义一个卷积核
kernel = np.ones(10) / 10

# 执行卷积操作
convolved_signal = convolve(signal, kernel, mode='same')

# 绘制结果
plt.plot(t, signal, 'b-', label='original signal')
plt.plot(t, convolved_signal, 'g-', linewidth=2, label='convolved signal')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

在这段代码中,首先生成了一个包含噪声的正弦信号。然后,定义了一个简单的卷积核,该卷积核是一个长度为10的向量,每个元素都是1/10。通过convolve函数,将卷积核应用于信号,实现了信号的平滑。最后,使用Matplotlib绘制了原始信号和卷积后的信号,以直观地展示卷积的效果。

1.3 傅里叶变换

傅里叶变换是一种将信号从时域转换到频域的数学工具。通过傅里叶变换,可以分析信号的频率成分,这对于信号处理和分析非常重要。在数字信号处理中,最常用的傅里叶变换是离散傅里叶变换(DFT),而快速傅里叶变换(FFT)是DFT的一种高效实现。

在SciPy中,scipy.fft模块提供了执行傅里叶变换的函数。下面将通过一个简单的例子来学习如何使用SciPy进行傅里叶变换。

1.3.1 傅里叶变换示例

假设有一个包含多个频率成分的信号,希望使用傅里叶变换来分析这些频率成分。

from scipy.fft import fft, fftfreq

# 生成一个包含多个频率成分的信号
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 10 * t)

# 执行傅里叶变换
N = len(signal)
yf = fft(signal)
xf = fftfreq(N, 1 / fs)[:N//2]

# 绘制结果
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
plt.grid()
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.show()

在这里插入图片描述
在这段代码中,首先生成了一个包含两个频率成分的信号。然后,使用fft函数执行了傅里叶变换,并使用fftfreq函数生成了频率轴。最后,使用Matplotlib绘制了信号的频谱图,展示了信号的频率成分及其幅度。

通过本课程的学习,学员将能够使用SciPy的信号处理模块进行基本的信号处理操作,包括滤波、卷积和傅里叶变换。


网站公告

今日签到

点亮在社区的每一天
去签到