Engee 文档
Notebook

用滑动平均法过滤噪声信号

本例展示了如何使用Moving RMS 程序块执行移动平均(简单和指数)滤波。通过更改程序块的设置,我们可以获得四种不同的滤波效果。

模型和滤波器说明

程序块Pulse Generator 生成每个 512 个时间采样的矩形脉冲。程序块Switch 控制上下蜿蜒水平(0.5 和 1.5 之间)的切换。我们在信号中加入数学期望值为 0、方差为 0.001 的噪声。

对于采用滑动窗口法(移动平均法(MA))或 FIR 滤波器进行平滑处理,我们采用了两种不同的窗口重叠率模式。在一种情况下,滤波器会对 1 次测量进行跳变,而在另一种情况下,则会对 4 次测量进行跳变。就输出值而言,这些滤波器的结果几乎相同,但重叠率为 4 的滤波器的离散化程度将比跳变率为 1 的滤波器低 4 倍。

我们还实施了一组指数平滑(指数移动平均(EMA))的 BIR 滤波器,并为其设置了不同的权重系数:0.9 和 0.99。它们对输出信号的影响非常明显:平滑系数值(0.9)较小的图形对噪声和信号电平之间的切换反应更加灵敏。

有关这些平滑方法的操作及其参数的更多详情,请参阅 [移动有效值] 块帮助 (https://engee.com/helpcenter/stable/dsp-statistics/moving-rms.html)。

image.png

使用封装 SVG 标记的注释来突出显示模型的各个区域。

模型采样率

由于在Engee中需要指定模型的步长,因此在使用多阶模型时需要注意不同区块的离散化。让我们来看一种情况。噪声发生器的触发频率是脉冲发生器的 512 倍。模型配置为每秒产生 44100 次测量。

如果第一个平滑滤波器的平滑窗口跳变大小为 4,那么经过该滤波器后的信号采样率将等于 (512/4)/44100,即 128/44100 (我们可以说是 128 个采样点)

但是,如果我们想让跳变大小等于 5,就必须改变模型的基本采样率。事实上,在这种滤波器的输出端,信号的采样率为 (512/5)/44100,即 102.4/44100(小数采样率)。在这种情况下,模型的基本采样率不再是画布上所有信号采样率的共同除数。需要将其提高 5 倍 (5*44100) 才能恢复模型的性能。

运行模型

让我们通过程序控制来运行模型,并比较不同过滤器的结果。

In [ ]:
modelName = "mvgRMSNoisyStep";
model = modelName in [m.name for m in engee.get_all_models()] ? engee.open( modelName ) : engee.load( "$(@__DIR__)/$(modelName).engee");
engee.set_param!( modelName, "StopTime"=>8 );
data = engee.run( modelName, verbose=false )
Out[0]:
Dict{String, DataFrame} with 5 entries:
  "MA - Размер скачка 4"              => 88201×2 DataFrame…
  "MA - Размер скачка 1"              => 352801×2 DataFrame…
  "EMA - Показатель сглаживания 0.9"  => 352801×2 DataFrame…
  "EMA - Показатель сглаживания 0.99" => 352801×2 DataFrame…
  "Зашумленные импульсы"              => 352801×2 DataFrame

绘制总图:

In [ ]:
plot( data["Зашумленные импульсы"].time[1:4:end], data["Зашумленные импульсы"].value[1:4:end],
    c=5, label="Зашумленные импульсы" )
plot!( data["MA - Размер скачка 4"].time[1:4:end], data["MA - Размер скачка 4"].value[1:4:end],
    c=1, label="Размер скачка 4" )
plot!( data["MA - Размер скачка 1"].time[1:4:end], data["MA - Размер скачка 1"].value[1:4:end],
    c=2, label="Размер скачка 1" )
plot!( data["EMA - Показатель сглаживания 0.9"].time[1:4:end], data["EMA - Показатель сглаживания 0.9"].value[1:4:end],
    c=3, label="Показатель сглаживания 0.9" )
plot!( data["EMA - Показатель сглаживания 0.99"].time[1:4:end], data["EMA - Показатель сглаживания 0.99"].value[1:4:end],
    c=4, label="Показатель сглаживания 0.99" )
Out[0]:

让我们放大图表,看看不同的平滑算法如何处理信号电平的突然变化。

In [ ]:
r1 = 65500:65800
r2 = 4 .* r1

plot( data["Зашумленные импульсы"].time[r2], data["Зашумленные импульсы"].value[r2],
       c=5, label="Зашумленные импульсы" )
plot!( data["MA - Размер скачка 4"].time[r1], data["MA - Размер скачка 4"].value[r1],
        c=1, label="Размер скачка 4" )
plot!( data["MA - Размер скачка 1"].time[r2], data["MA - Размер скачка 1"].value[r2],
        c=2, label="Размер скачка 1" )
plot!( data["EMA - Показатель сглаживания 0.9"].time[r2], data["EMA - Показатель сглаживания 0.9"].value[r2],
        c=3, label="Показатель сглаживания 0.9" )
plot!( data["EMA - Показатель сглаживания 0.99"].time[r2], data["EMA - Показатель сглаживания 0.99"].value[r2],
        c=4, label="Показатель сглаживания 0.99" )
Out[0]:

结论

我们比较了几种借助Moving RMS 块以不同设置进行信号平均的方法,我们可以实施我们需要的算法,并客观地选择最佳滤波方法。