def generatesignal(t,freqs,amps,phases,SNR): """ 根据指定的频率、幅度、相位、信噪比等参数生成信号片段 :param t: 生成信号的时间序列 :param freqs: 生成信号的频率参数,多个成分以列表形式组织 :param amps: 生成信号的幅度参数,多个成分以列表形式组织 :param phases: 生成信号的相位参数,多个成分以列表形式组织 :param SNR: 生成信号的高斯噪声信噪比参数 :return: 生成的信号片段 """ t = np.array(1) sig = np.zeros(np.shape(t)) for freq,amp,phase in zip(freqs,amps,phases): sig = sig + amp*np.sin(2*np.pi*freq*t+phase) noise = np.random.normal(loc = 0, scale = 1/np.exp(SNR/10),size = np.shape(t)) sig = sig + noise return sig def signalProcessByCon(sig,h,mode='same',method = None): """ 通过不同卷积方式实现FIR滤波器滤波功能 :param sig: 待处理信号 :param h: FIR滤波器单位脉冲响应 :param mode: 卷积输出类型 :param method: 卷积计算方法 :return: 返回滤波结果和卷积运算时间 """ start_time = time.time() if method is None: y = signal.convolve(sig,h,mode = mode, method = 'auto') elif method == 'overlap_add': y = signal.oaconvolve(sig,h,mode = mode) else: y = signal.convolve(sig,h,mode=mode,method = method) end_time = time.time() return y,end_time-start_time def drawSignalCur(tim,sig): """ 画出信号时域波形 :param tim: 信号片段的时间坐标 :param sig: 信号片段值 :return: 无返回值 """ plt.figure(figsize=(10, 4)) plt.plot(tim, sig) plt.xlabel('Time[s]') plt.ylabel('Amp') plt.title('Signal') plt.grid() plt.show() def drawspecrum(sig,Fs): """ 画出信号的频谱,包括幅度谱和相位谱 :param sig: 需要绘制的信号片段 :param Fs: 信号采样频率 :return: 无返回值 """ hs = fftpack.rfft(sig) dur = 1.0/Fs num = len(sig) fs = fftpack.rfftfreq(num,dur) fig = plt.figure(figsize=(10, 6)) # Plot Magnitude response sub1 = plt.subplot(2, 1, 1) sub1.plot(fs, np.abs(hs), 'r', linewidth=2) sub1.set_title('Magnitude Response', fontsize=20) sub1.set_xlabel('Frequency [Hz]', fontsize=20) sub1.set_ylabel('Magnitude [dB]', fontsize=20) sub1.grid() # Plot phase angle sub2 = plt.subplot(2,
时间: 2025-04-02 16:12:52 浏览: 44
<think>嗯,用户想知道如何在Python里实现信号生成、FIR滤波器处理,以及绘制时域和频谱图。首先,我需要整理一下步骤。信号生成的话,通常会用numpy生成正弦波或者余弦波,再加上噪声。比如,用户提到的引用[2]里用了余弦信号加噪声,这个可以借鉴。
接下来是FIR滤波器的设计。我记得scipy.signal里的firwin函数可以设计FIR滤波器,需要指定抽头数和截止频率。比如引用[2]和[4]都用了firwin,所以这里应该用这个函数来生成系数。然后,应用滤波器的话,可以用lfilter或者sosfilt,不过引用[2]用的是lfilter,用户可能更倾向于这个方法。
然后是处理后的信号的可视化,包括时域图和频谱图。时域图直接用matplotlib的plot就行,频谱的话可能需要用fft计算,然后绘图。引用[1]里用了fft和绘图,可以参考这部分代码。
用户提到的引用[3]和[4]还提到了Hilbert变换和包络线,不过当前问题可能不需要这些,但可以留到相关问题里。另外,需要注意代码的结构,先生成信号,再设计滤波器,应用滤波,最后绘图。
可能需要注意的点:采样率的设置是否正确,滤波器设计时的Nyquist频率是否正确,以及绘图时的横轴单位转换是否正确。比如,引用[2]里把频率转换成Hz,可能需要除以π乘以采样率的一半。
测试信号部分,用户例子中的信号是余弦加上高频噪声,这样能更好展示滤波效果。然后,滤波后的信号应该保留低频成分,去除高频噪声,所以在时域和频域图上都要有明显变化。
最后,生成相关问题的时候,可以考虑优化方法、不同滤波器的比较,或者实时处理的应用,这些都在引用里有提到过。</think>### Python信号处理实现步骤
#### 一、信号生成与处理流程
1. **生成测试信号**
- 使用$f(t)=A\cos(2\pi f_0 t)$创建基础信号
- 添加高斯白噪声模拟真实环境干扰
- 代码示例:
```python
import numpy as np
fs = 1000 # 采样率
t = np.linspace(0, 1, fs) # 时间轴
f0 = 50 # 基频
signal = 0.5 * np.cos(2*np.pi*f0*t) # 干净信号
noise = 0.2 * np.random.randn(len(t)) # 噪声
raw_signal = signal + noise # 含噪信号
```
2. **FIR滤波器设计**
- 使用`scipy.signal.firwin()`设计线性相位滤波器
- 参数选择依据:
- 抽头数$N$决定过渡带宽($N↑→过渡带↓$)
- 截止频率需归一化为Nyquist频率的分数
- 设计示例:
```python
from scipy import signal
numtaps = 101 # 滤波器阶数
cutoff = 60 # 截止频率(Hz)
nyq = 0.5 * fs # Nyquist频率
b = signal.firwin(numtaps, cutoff/nyq, window='hamming')
```
3. **信号滤波处理**
- 使用零相位滤波保持信号特征[^3]
- 执行两次滤波消除相位偏移
```python
filtered = signal.filtfilt(b, [1.0], raw_signal)
```
#### 二、可视化实现
1. **时域对比图**
```python
import matplotlib.pyplot as plt
plt.figure(figsize=(12,6))
plt.subplot(211)
plt.plot(t[:200], raw_signal[:200], 'b', label='原始信号')
plt.plot(t[:200], filtered[:200], 'r', label='滤波信号')
plt.legend()
```
2. **频域分析图**
- 使用FFT计算频谱密度
- 示例代码:
```python
from scipy.fft import fft
n = len(raw_signal)
freq = np.fft.fftfreq(n, d=1/fs)[:n//2]
plt.subplot(212)
plt.semilogy(freq, np.abs(fft(raw_signal))[:n//2], 'b')
plt.semilogy(freq, np.abs(fft(filtered))[:n//2], 'r')
plt.xlim(0, 200)
plt.xlabel('Frequency (Hz)')
plt.grid(True)
```
#### 三、完整代码结构
```python
# 完整示例代码
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
# 信号生成
fs = 1000
t = np.linspace(0, 1, fs)
f0 = 50
clean = 0.5 * np.cos(2*np.pi*f0*t)
noisy = clean + 0.2 * np.random.randn(fs)
# 滤波器设计
numtaps = 101
cutoff = 60
nyq = 0.5 * fs
b = signal.firwin(numtaps, cutoff/nyq, window='hamming')
# 信号滤波
filtered = signal.filtfilt(b, [1.0], noisy)
# 可视化
plt.figure(figsize=(12,8))
# 时域图
plt.subplot(211)
plt.plot(t[:200], noisy[:200], 'b', alpha=0.5)
plt.plot(t[:200], filtered[:200], 'r')
plt.title('时域信号对比')
# 频域图
plt.subplot(212)
n = len(noisy)
freq = np.fft.fftfreq(n, d=1/fs)[:n//2]
plt.semilogy(freq, np.abs(np.fft.fft(noisy))[:n//2], 'b', alpha=0.5)
plt.semilogy(freq, np.abs(np.fft.fft(filtered))[:n//2], 'r')
plt.xlim(0, 200)
plt.title('频域特性对比')
plt.tight_layout()
plt.show()
```
阅读全文
相关推荐


















