Engee 文档
Notebook

系统对象在信号处理中的应用

EngeeDSP库包含使用系统对象进行信号处理的强大工具,系统对象是流数据处理的专用组件。 下面的代码演示了一种综合的信号处理方法,它将EngeeDSP系统对象与传统的信号处理功能相结合。

让我们列出实现的关键特性。

  1. 使用系统对象 SineWaveDSP 以产生具有可配置参数(幅度,频率,计算方法)的信号。
  2. 申请表格 DescretFIRFilter 以在流模式下过滤信号。
  3. 与通常的处理函数集成(通过卷积滚动平均)。
  4. 将EngeeDSP的面向对象方法与Julia的过程方法相结合。

让我们从连接这个项目中使用的库开始。

In [ ]:
# Pkg.add("DSP")
# Pkg.add("Statistics")

using DSP
using EngeeDSP
using Statistics

现在让我们执行初始化。 下面的代码创建一个系统对象。 SineWaveDSP来自EngeeDSP库,用于生成具有指定参数的正弦信号:幅度 A = 0.8、频率 f = 100 Гц、采样率 **fs = 1000 Гц,**帧的大小 **framesize = 796**计数。

对象配置为表格式计算方法(Table lookup),实际输出(Real)和连续生成模式(Continuous).

In [ ]:
A = 0.8
f = 100
fs = 1000
framesize = 796

H = EngeeDSP.SineWaveDSP(
    Amplitude = A,
    Frequency = f,
    SampleTime = 1//fs,
    SamplesPerFrame = framesize,
    ComputationMethod = "Table lookup",
    OutputComplexity = "Real",
    SampleMode = "Continuous"
)
Out[0]:
SineWaveDSP:
    Amplitude=0.8
    Frequency=100
    PhaseOffset=0
    SampleMode=Continuous
    OutputComplexity=Real
    ComputationMethod=Table lookup
    SampleTime=1152921504606847//1152921504606846976
    SamplesPerFrame=796
    ResettingStatesWhenReEnabled=Restart at time zero

下面的代码创建一个系统对象 DescretFIRFilter,其是具有基本默认配置的FIR滤波器,并且具有以下特性:

  • CoefSource=Dialog parameters-系数,在这种情况下它是一个数组[0.5 0.5],它对应于最简单的平均滤波器。
  • FilterStructure=Direct form-使用标准的直接过滤器实现结构。
  • InputProcessing=Elements as channels-每个输入样本作为一个单独的通道进行处理。
  • InitialStates=0-滤波器的初始状态为零。
  • **ShowEnablePort=false**及 ExternalReset=None-过滤器连续运行,无需外部复位控制。

此对象设计用于流式信号处理,并存储内部状态(PreEmphasis_states=[0.0])之间的通话。

In [ ]:
fir_filter = EngeeDSP.DescretFIRFilter() 
Out[0]:
DescretFIRFilter:
    CoefSource=Dialog parameters
    FilterStructure=Direct form
    Coefficients=[0.5 0.5]
    InputProcessing=Elemets as channels
    InitialStates=0
    ShowEnablePort=false
    ExternalReset=None
    PreEmphasis_states=[0.0]

下面显示了创建一个知己平均滤波器,窗口为10个样本。 阵列 **averaging_filter**充满价值 1/window_size(即 0.1),这意味着均匀地称重信号的所有10个先前值。 该滤波器抑制高频噪声,通过在给定窗口上平均来平滑信号。 与EngeeDSP系统对象不同,它是一个静态卷积,不会保存调用之间的状态。

In [ ]:
window_size = 10
averaging_filter = ones(window_size) / window_size
Out[0]:
10-element Vector{Float64}:
 0.1
 0.1
 0.1
 0.1
 0.1
 0.1
 0.1
 0.1
 0.1
 0.1

现在让我们从我们的对象中构建一个模型。 下面的代码以100步执行循环信号生成和处理:

  1. 信号生成:
    -在每一步 H() 生成新的正弦波帧(长度 framesize=796 计数)通过系统对象 SineWaveDSP.
  2. 过滤:
    • y_fir = fir_filter(x) -应用流式FIR滤波器(带系数 [0.5, 0.5] 到信号,保存通话之间的状态。
    • y_avg = conv(y_fir, averaging_filter)[1:length(y_fir)] -另外用移动平均线(10个样本的窗口)平滑信号,将卷积的结果修剪到原始长度。
  3. 保存结果:
    -来源(s),过滤(fir_filtered)和平滑(avg_filtered)将信号累加在阵列中以供后续分析。
In [ ]:
# Генерируем и обрабатываем сигнал
s = Float64[]          # Исходный сигнал
fir_filtered = Float64[] # После FIR фильтра
avg_filtered = Float64[] # После усреднения

for n in 1:100
    x = H()
    y_fir = fir_filter(x)
    y_avg = conv(y_fir, averaging_filter)[1:length(y_fir)] # Усекаем до исходной длины
    
    append!(s, x)
    append!(fir_filtered, y_fir)
    append!(avg_filtered, y_avg)
end

现在我们将使用保存的数据来构建图表。

In [ ]:
gr()
n_show = 100
t = (0:n_show-1)/fs

p_signals = plot(t, s[1:n_show], label="Исходный сигнал", linewidth=2)
plot!(t, fir_filtered[1:n_show], label="После FIR", linewidth=2, linestyle=:dash)
plot!(t, avg_filtered[1:n_show], label="После усреднения", linewidth=2, linestyle=:dot)
title!("Сигналы на разных этапах обработки")
xlabel!("Время (с)")
ylabel!("Амплитуда")
Out[0]:

图表结果:

-原始信号(实线)是振幅为0.8的纯正弦。
-Fir之后(虚线)是具有减少的急剧波动(窗口2参考的影响)的平滑信号。
-平均(点)后,前10个点显示平均信号的增加(滤波器"填满"),然后归零,因为 conv 它被修剪到输入信号的长度,而不填充边缘。

为什么是零?
移动平均线需要 window_size-1 完全重叠的额外计数。 在代码中 conv 它被严格地切割成长度 y_fir 丢弃卷积的"不完整"部分—因此第10点之后的零,平均后的零值-是处理的伪像,而不是系统的真实行为。 对于流式平均,最好应用 DSP.filt(averaging_filter, y_fir) 具有保存状态。

In [ ]:
s = Float64[]         
fir_filtered = Float64[] 
avg_filtered = Float64[] 

for n in 1:100
    x = H() 
    y_fir = fir_filter(x) 
    y_avg, filt_state = DSP.filt(averaging_filter, y_fir)
    
    append!(s, x)
    append!(fir_filtered, y_fir)
    append!(avg_filtered, y_avg)
end

p_signals = plot(t, s[1:n_show], label="Исходный сигнал", linewidth=2)
plot!(t, fir_filtered[1:n_show], label="После FIR", linewidth=2, linestyle=:dash)
plot!(t, avg_filtered[1:n_show], label="После усреднения", linewidth=2, linestyle=:dot)
title!("Сигналы на разных этапах обработки")
xlabel!("Время (с)")
ylabel!("Амплитуда")
Out[0]:

切换到 filt 我消除了剪切工件,图形现在反映了系统的真实行为,它还允许我们创建一个完全流处理系统,其中:

  1. FIR滤波器(样本窗口2)平滑平滑信号(虚线);
  2. 移动平均线(10个样本的窗口)现在正确处理整个信号而没有零;
  3. 由于两个过滤器都在有状态流模式下运行,因此过滤器之间的相移已变得可预测。

结论

该示例清楚地演示了组合方法的优点,其中EngeeDSP系统对象用于流处理,而传统函数用于额外的转换。 最终的图表特别具有指示性,它允许您跟踪模型每个阶段的信号变化。 将Engee系统对象与传统的Julia方法相结合,为创建高效灵活的信号处理系统开辟了广泛的可能性。