带通滤波器等效幅度

信息处理 fft 频谱 频率 带通 振幅
2022-02-01 09:41:41

我有一个信号,我正在使用带通滤波器来限制频率范围。我也有兴趣通过它们的幅度过滤信号中的剩余频率(在带通滤波之后)。因此,例如,如果我将带通滤波器设置为排除 20-100 Hz 范围之外的频率,我还需要一个“幅度滤波器”来排除剩余分量,如果它们的幅度范围超出例如 0.2-0.8。

请参阅下面的粗图。应保留黑色矩形内的区域。

在此处输入图像描述

请让我知道是否:

  • 存在这样的算法
  • 如果是这样,在 python、Julia、R、Octave、Matlab 等中是否有任何实现?
  • 如果没有,要搜索哪些关键字以了解有关此主题的更多信息?

谢谢你。

1个回答

这可以通过分析时频表示来完成,如 CWT 或 STFT。然而,必须精确地知道目标才能获得所需的结果,因为时间和频率是耦合的,单独的目标幅度可能会产生失真。步骤是:

  1. 转换为时频
  2. 零不需要的幅度
  3. 倒置

下面我生成线性调幅余弦,使用两个小波设置的同步压缩 CWT 排除 0.2-0.8 之外的幅度,并将结果与​​已排除的幅度生成的相同余弦进行比较。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

它不会总是很好地解决这个问题。

与非同步压缩 CWT/STFT 相比的优势在于合并了频繁不确定性包络,这些包络会留下残余分量,如下所示:

在此处输入图像描述 在此处输入图像描述

澄清“剩余分量”:x轴=时间,y轴=频率;缩放:

这些是根据不确定性原理:比“真实频率”稍高和稍低的频率与非零值相关,但它们离“真实频率”越远,相关性越弱,因此按幅度进行阈值处理将保持这些“剩余" 频率,而在 SSQ 中,它们被合并并丢弃在一起。


代码

使用squeezepy

import numpy as np
from ssqueezepy import cwt, icwt, Wavelet, ssq_cwt, issq_cwt
from ssqueezepy.visuals import imshow, plot

def filter_amplitude(x, xtarget, amin, amax, transform=ssq_cwt):   
    wavelet = Wavelet(('gmw', {'beta': 60}))
    S = transform(x, wavelet)[0]

    name = transform.__name__.upper()
    imshow(S, abs=1, title="abs(%s)" % name)

    Sa = np.abs(S)
    S[Sa < amin * Sa.max()] = 0
    S[Sa > amax * Sa.max()] = 0
    imshow(S, abs=1, title="abs(%s) | amplitude-filtered" % name)
    
    transform_inverse = issq_cwt if name == 'SSQ_CWT' else icwt
    xrec = transform_inverse(S, wavelet)

    ##########################################################################
    mae = np.mean(np.abs(xtarget - xrec))
    plot(xrec, ylims=(-1, 1), title="result", show=1)
    plot(xrec, ylims=(-1, 1), title="overlapped with target | MAE=%.3f" % mae)
    plot(xtarget, show=1)

#%%########################################################################### 
N = 2049
amin, amax = .2, .8

t = np.linspace(0, 1, N, 1)
A = np.linspace(0, 1, N, 1)
c = np.cos(2*np.pi * 64 * t)

x = c * A
xtarget = c * A * ((A > amin) * (A < amax))

plot(x,       title="input",  ylims=(-1, 1), show=1)
plot(xtarget, title="target", ylims=(-1, 1), show=1)

#%%
filter_amplitude(x, xtarget, amin, amax, transform=ssq_cwt)
filter_amplitude(x, xtarget, amin, amax, transform=cwt)