第三章 信号预处理技术:信号去噪方法、趋势项去除、信号重采样与截断

各位工程师朋友,大家好。欢迎来到《风机轴承故障诊断实战手册》的第三章。

上一章我们聊了传感器怎么选、怎么装,拿到了原始振动信号。但说实话,现场采集到的信号,那叫一个「脏」。有环境噪声、有齿轮箱的干扰、有安装面的共振,甚至还有电缆的工频干扰。你要是直接把这种信号拿去分析,结果基本没法看。

所以,信号预处理这一步,我把它叫做「洗菜」。菜不洗干净,再好的厨子也做不出好菜。今天我们就来聊聊这三道「清洗工序」:去噪、去趋势、重采样与截断。

信号预处理技术知识体系 原始振动信号 ① 信号去噪 ② 趋势项去除 ③ 重采样与截断 小波阈值去噪 软阈值 / 硬阈值 / 自适应阈值 小波基选择:db4, sym8, coif5 EMD 去噪 IMF 筛选 + 部分重构 模态混叠问题需注意 多项式拟合 最小二乘法 阶次选择经验 高通滤波 截止频率 0.5~2 Hz 零相位滤波 重采样 降采样 / 升采样 抗混叠滤波器 信号截断 整周期截取 窗函数处理

3.1 信号去噪方法

现场采集的振动信号,噪声来源五花八门。我见过最夸张的一次,是在某风电场的机舱里,传感器信号里居然混进了对讲机的电磁干扰。你想想看,那频谱图上一堆莫名其妙的尖峰,差点把我带沟里去。

去噪的方法很多,但做轴承故障诊断,我个人最常用的是两种:小波去噪EMD去噪。下面一个一个说。

3.1.1 小波阈值去噪

小波去噪的原理,说白了就是:信号在小波域里,有用成分的能量集中在少数大系数上,而噪声均匀分布在小系数上。我们设一个阈值,把小于阈值的系数干掉或压缩,再重构回来,噪声就没了。

这里有个关键点——阈值怎么选?

  • 硬阈值:小于阈值的直接置零。好处是信号边缘保留得好,坏处是容易产生伪吉布斯震荡,信号看起来「毛刺刺」的。
  • 软阈值:小于阈值的置零,大于阈值的向零收缩。平滑性好,但会损失一点幅值精度。
  • 自适应阈值:根据每层小波系数的统计特性动态调整。我一般用这个,效果最稳。

重要经验:小波基的选择直接影响去噪效果。做轴承故障诊断,我推荐 db4sym8coif5。分解层数一般设 3~5 层,太多会把有用信号也滤掉。

下面给一段 Python 代码,用的是 PyWavelets 库。这段代码我在好几个项目里直接复用,改改参数就能用。

import pywt
import numpy as np

def wavelet_denoise(signal, wavelet='db4', level=4, mode='soft'):
    """
    小波阈值去噪
    signal : 原始信号 (1D array)
    wavelet: 小波基名称
    level  : 分解层数
    mode   : 'soft' 或 'hard'
    """
    # 小波分解
    coeffs = pywt.wavedec(signal, wavelet, level=level)
    
    # 计算阈值(通用阈值公式)
    sigma = np.median(np.abs(coeffs[-1])) / 0.6745
    threshold = sigma * np.sqrt(2 * np.log(len(signal)))
    
    # 对每一层细节系数进行阈值处理(近似系数保留)
    coeffs_thresh = [coeffs[0]]  # 近似系数不动
    for i in range(1, len(coeffs)):
        coeffs_thresh.append(pywt.threshold(coeffs[i], threshold, mode=mode))
    
    # 重构信号
    denoised = pywt.waverec(coeffs_thresh, wavelet)
    return denoised

# 使用示例
# clean_signal = wavelet_denoise(raw_signal, wavelet='sym8', level=4, mode='soft')

我的小技巧:如果你不确定小波基选哪个,可以先用 sym8 试试。我在多个风机轴承数据上对比过,sym8 在去噪和保留冲击特征之间平衡得最好。

3.1.2 EMD 去噪

EMD(经验模态分解)是另一种思路。它不需要预设基函数,完全靠数据驱动,把信号分解成若干个 IMF(本征模态函数)。

噪声通常集中在高频 IMF 分量里。我们只需要把前几个高频 IMF 扔掉,用剩下的 IMF 重构信号就行。

但这里有个坑——模态混叠。有时候噪声和有用信号会混在同一个 IMF 里,你一刀切掉,有用信息也跟着没了。我曾经在一个齿轮箱轴承的案例里吃过这个亏,去噪后故障特征反而变弱了。

怎么解决?我建议用 EEMD(集合经验模态分解)CEEMDAN,它们通过添加白噪声来抑制模态混叠,效果要好得多。

from PyEMD import EEMD
import numpy as np

def eemd_denoise(signal, max_imf=8, noise_width=0.2, trials=100):
    """
    EEMD 去噪
    signal    : 原始信号
    max_imf   : 保留的最大 IMF 阶数(前几阶高频去掉)
    noise_width: 添加白噪声的幅值(标准差比例)
    trials    : 集成次数
    """
    eemd = EEMD(trials=trials, noise_width=noise_width)
    imfs = eemd(signal)
    
    # 去掉前 max_imf 个高频 IMF,其余重构
    denoised = np.sum(imfs[max_imf:], axis=0)
    return denoised

# 使用示例
# clean_signal = eemd_denoise(raw_signal, max_imf=3, noise_width=0.2, trials=100)

注意:EEMD 的计算量比较大,100 次集成在长信号上可能要跑几十秒。如果现场需要实时处理,建议用小波去噪。离线分析用 EEMD 没问题。


3.2 趋势项去除

什么是趋势项?就是信号中缓慢变化的、低频的漂移成分。比如传感器温漂、安装基座的缓慢变形、甚至风机的偏航动作,都会在振动信号里叠加一个缓慢变化的趋势。

这个趋势如果不去掉,在频谱分析时会在低频段产生很大的能量,把轴承故障特征频率给淹没了。我见过有人拿着带趋势项的信号去做包络谱,结果低频段一片红,根本找不到故障频率在哪。

去除趋势项,我常用的方法有两种:

3.2.1 多项式拟合去除

思路很简单:用多项式拟合出信号的趋势,然后用原始信号减去这个趋势。

  • 一次多项式:去除线性趋势。适合传感器温漂这类情况。
  • 二次或三次多项式:去除非线性趋势。适合更复杂的漂移。

阶次怎么选?我的经验是:先试一次,如果频谱低频还有明显隆起,再试二次。一般不超过三次,阶次太高会把有用信号也拟合进去。

import numpy as np

def remove_trend(signal, order=1):
    """
    多项式拟合去除趋势项
    signal : 原始信号
    order  : 多项式阶数
    """
    t = np.arange(len(signal))
    coeffs = np.polyfit(t, signal, order)
    trend = np.polyval(coeffs, t)
    detrended = signal - trend
    return detrended

# 使用示例
# clean_signal = remove_trend(raw_signal, order=1)

3.2.2 高通滤波去除

另一种思路是用高通滤波器,直接把低频趋势滤掉。截止频率一般设在 0.5 Hz ~ 2 Hz 之间。

这里要注意:一定要用零相位滤波(比如 scipy 的 filtfilt),否则滤波后的信号会有相位偏移,影响后续的时域分析。

from scipy.signal import butter, filtfilt

def highpass_filter(signal, cutoff=1.0, fs=2560, order=4):
    """
    高通滤波去除趋势项
    signal : 原始信号
    cutoff : 截止频率 (Hz)
    fs     : 采样频率 (Hz)
    order  : 滤波器阶数
    """
    nyquist = 0.5 * fs
    normal_cutoff = cutoff / nyquist
    b, a = butter(order, normal_cutoff, btype='high', analog=False)
    filtered = filtfilt(b, a, signal)
    return filtered

# 使用示例
# clean_signal = highpass_filter(raw_signal, cutoff=1.0, fs=2560)

我的建议:如果趋势项比较平滑(比如温漂),用多项式拟合更干净。如果趋势项里还混着一些低频干扰(比如 0.5 Hz 的摆动),用高通滤波更省事。我一般两个都试一下,看哪个效果更好。


3.3 信号重采样与截断

3.3.1 重采样

重采样,说白了就是改变信号的采样率。什么时候需要重采样?

  • 降采样:原始采样率太高(比如 25.6 kHz),数据量太大,分析起来慢。降到 2560 Hz 或 5120 Hz 就够用。
  • 升采样:需要提高时间分辨率,或者要匹配另一个信号的采样率。
  • 角域重采样:在阶次分析中,把等时间间隔的信号变成等角度间隔的信号。这个我们后面章节会细讲。

降采样时有个大坑——抗混叠滤波。直接降采样会产生频率混叠,高频成分会折叠到低频段,让你误以为有故障特征。所以降采样前必须先做低通滤波,截止频率设为新采样率的一半。

from scipy.signal import resample, decimate

# 方法1:使用 scipy.signal.resample(基于 FFT,适合整数倍重采样)
def resample_signal(signal, orig_fs, target_fs):
    num_samples = int(len(signal) * target_fs / orig_fs)
    resampled = resample(signal, num_samples)
    return resampled

# 方法2:使用 scipy.signal.decimate(自带抗混叠滤波,适合降采样)
# new_signal = decimate(raw_signal, q=10)  # q 为降采样倍数

重要提醒:重采样后,信号的频率分辨率会变化。比如原始信号 1 秒有 2560 个点,降采样到 1280 Hz 后,1 秒只有 1280 个点,频率分辨率从 1 Hz 变成 0.5 Hz?不对,实际上是变差了。你想想看,采样率降低,相同时间内的点数变少,频率分辨率 = 采样率 / 点数,所以分辨率不变?嗯,这里容易搞混,建议你实际算一下。

3.3.2 信号截断

信号截断,就是从一个长信号里切出一段来用。为什么要截断?

  • 风机轴承信号通常连续采集几十分钟甚至几小时,我们只需要分析其中一段稳态数据。
  • FFT 分析要求输入信号长度是 2 的幂次(比如 1024、2048、4096),方便快速计算。
  • 有时候需要截取包含故障冲击的特定时间段。

截断时要注意频谱泄漏。直接截断相当于加了一个矩形窗,会在频谱上产生旁瓣,把能量泄漏到相邻频率上。解决办法是加窗函数,比如汉宁窗、海明窗。

import numpy as np

def truncate_and_window(signal, start, length, window='hann'):
    """
    信号截断并加窗
    signal : 原始信号
    start  : 起始点
    length : 截取长度
    window : 窗函数类型
    """
    segment = signal[start:start+length]
    
    if window == 'hann':
        win = np.hanning(length)
    elif window == 'hamming':
        win = np.hamming(length)
    elif window == 'blackman':
        win = np.blackman(length)
    else:
        win = np.ones(length)  # 矩形窗
    
    return segment * win

# 使用示例
# segment = truncate_and_window(raw_signal, start=10000, length=4096, window='hann')

核心经验:做轴承故障诊断时,我习惯截取 4096 或 8192 个点。这个长度在频率分辨率和计算速度之间比较平衡。如果故障特征频率很低(比如 10 Hz 以下),可能需要更长的截断长度来提高频率分辨率。


本章小结

好了,信号预处理的三板斧讲完了。我们来捋一捋:

  1. 去噪:小波去噪适合大多数场景,速度快、效果好;EMD 去噪适合非平稳信号,但计算量大。
  2. 去趋势:多项式拟合和高通滤波都能用,看趋势项的特点来选。
  3. 重采样与截断:降采样别忘了抗混叠滤波,截断记得加窗。

这些预处理步骤,我建议你每次拿到新数据都走一遍。别嫌麻烦,预处理做得好,后面的分析事半功倍。我曾经在一个项目里,光是在去噪参数上调试了两天,最后故障特征清晰得像教科书一样。

下一章我们会进入真正的「诊断」环节——时域分析。到时候你会看到,预处理做没做好,在时域波形上一眼就能看出来。


专注资料整理