如何用Python去除50Hz-10kHz线性调频(chirp)信号中的平稳噪声
去除平稳噪声保留线性调频信号的Python实现方案
针对混有平稳噪声的50Hz-10kHz线性调频信号,以下是几种高效的降噪方案,附Python实现代码:
1. 带通滤波(最直接方案)
因为已知信号的精确频率范围(50Hz-10kHz),带通滤波可以直接滤除带外的平稳噪声,是最直观的解决方案。推荐使用巴特沃斯滤波器,它在通带内具有平坦的幅频特性,能最大程度保留信号原始形态。
代码实现:
import numpy as np import matplotlib.pyplot as plt from scipy import signal # 生成测试信号:50Hz到10kHz的线性调频信号 + 平稳白噪声 fs = 44100 # 采样率,满足奈奎斯特准则(至少2倍最高频率) t = np.linspace(0, 1, fs, endpoint=False) chirp_signal = signal.chirp(t, f0=50, f1=10000, t1=1, method='linear') noise = np.random.normal(0, 0.5, len(chirp_signal)) noisy_signal = chirp_signal + noise # 设计巴特沃斯带通滤波器 lowcut = 50 highcut = 10000 order = 4 # 阶数越高过渡带越陡,按需调整 nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = signal.butter(order, [low, high], btype='band') # 应用滤波(filtfilt避免相位偏移) filtered_signal = signal.filtfilt(b, a, noisy_signal) # 绘图对比 plt.figure(figsize=(12, 8)) plt.subplot(3,1,1) plt.plot(t, chirp_signal) plt.title('原始线性调频信号') plt.subplot(3,1,2) plt.plot(t, noisy_signal) plt.title('混有平稳噪声的信号') plt.subplot(3,1,3) plt.plot(t, filtered_signal) plt.title('带通滤波后的信号') plt.tight_layout() plt.show()
2. 维纳滤波(利用噪声统计特性)
维纳滤波器通过估计信号和噪声的功率谱,最小化输出信号与原始信号的均方误差,适合平稳噪声场景。如果能获取纯噪声样本(比如信号未出现时的噪声片段),降噪效果会更精准。
代码实现:
from scipy.signal import wiener # 假设前1000个采样点为纯噪声样本 noise_sample = noisy_signal[:1000] noise_var = np.var(noise_sample) # 应用维纳滤波 wiener_filtered = wiener(noisy_signal, mysize=5, noise=noise_var) # 绘图对比 plt.figure(figsize=(12, 6)) plt.subplot(2,1,1) plt.plot(t, noisy_signal) plt.title('混有平稳噪声的信号') plt.subplot(2,1,2) plt.plot(t, wiener_filtered) plt.title('维纳滤波后的信号') plt.tight_layout() plt.show()
3. LMS自适应滤波(无需预先知道噪声特性)
最小均方(LMS)自适应滤波器通过迭代调整权重,实时跟踪并抵消平稳噪声,不需要预先知道噪声的频率范围或统计特性,适合噪声特性缓慢变化的平稳场景。
代码实现:
def lms_filter(input_signal, desired_signal, mu=0.001, order=100): """实现LMS自适应滤波""" n = len(input_signal) weights = np.zeros(order) output = np.zeros(n) for i in range(order, n): x = input_signal[i-order:i][::-1] output[i] = np.dot(weights, x) error = desired_signal[i] - output[i] weights += mu * error * x return output # 用噪声作为参考输入(实际场景可从系统其他通道获取独立噪声) ref_noise = noise.copy() lms_output = lms_filter(ref_noise, noisy_signal) # 绘图对比 plt.figure(figsize=(12, 6)) plt.subplot(2,1,1) plt.plot(t, noisy_signal) plt.title('混有平稳噪声的信号') plt.subplot(2,1,2) plt.plot(t, lms_output) plt.title('LMS自适应滤波后的信号') plt.tight_layout() plt.show()
方案选择建议:
- 已知信号精确频率范围时,优先选带通滤波,实现简单且效果稳定;
- 能获取纯噪声样本时,维纳滤波可进一步优化降噪效果;
- 无法预先获取噪声信息时,LMS自适应滤波是更灵活的选择。
内容的提问来源于stack exchange,提问作者VJA
相关产品推荐
相关产品推荐

