系统对象在信号处理中的应用
EngeeDSP库包含使用系统对象进行信号处理的强大工具,系统对象是流数据处理的专用组件。 下面的代码演示了一种综合的信号处理方法,它将EngeeDSP系统对象与传统的信号处理功能相结合。
让我们列出实现的关键特性。
- 使用系统对象
SineWaveDSP以产生具有可配置参数(幅度,频率,计算方法)的信号。 - 申请表格
DescretFIRFilter以在流模式下过滤信号。 - 与通常的处理函数集成(通过卷积滚动平均)。
- 将EngeeDSP的面向对象方法与Julia的过程方法相结合。
让我们从连接这个项目中使用的库开始。
# 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).
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"
)
下面的代码创建一个系统对象 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])之间的通话。
fir_filter = EngeeDSP.DescretFIRFilter()
下面显示了创建一个知己平均滤波器,窗口为10个样本。 阵列 **averaging_filter**充满价值 1/window_size(即 0.1),这意味着均匀地称重信号的所有10个先前值。 该滤波器抑制高频噪声,通过在给定窗口上平均来平滑信号。 与EngeeDSP系统对象不同,它是一个静态卷积,不会保存调用之间的状态。
window_size = 10
averaging_filter = ones(window_size) / window_size
现在让我们从我们的对象中构建一个模型。 下面的代码以100步执行循环信号生成和处理:
- 信号生成:
-在每一步H()生成新的正弦波帧(长度framesize=796计数)通过系统对象SineWaveDSP. - 过滤:
y_fir = fir_filter(x)-应用流式FIR滤波器(带系数[0.5, 0.5]到信号,保存通话之间的状态。y_avg = conv(y_fir, averaging_filter)[1:length(y_fir)]-另外用移动平均线(10个样本的窗口)平滑信号,将卷积的结果修剪到原始长度。
- 保存结果:
-来源(s),过滤(fir_filtered)和平滑(avg_filtered)将信号累加在阵列中以供后续分析。
# Генерируем и обрабатываем сигнал
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
现在我们将使用保存的数据来构建图表。
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!("Амплитуда")
图表结果:
-原始信号(实线)是振幅为0.8的纯正弦。
-Fir之后(虚线)是具有减少的急剧波动(窗口2参考的影响)的平滑信号。
-平均(点)后,前10个点显示平均信号的增加(滤波器"填满"),然后归零,因为 conv 它被修剪到输入信号的长度,而不填充边缘。
为什么是零?
移动平均线需要 window_size-1 完全重叠的额外计数。 在代码中 conv 它被严格地切割成长度 y_fir 丢弃卷积的"不完整"部分—因此第10点之后的零,平均后的零值-是处理的伪像,而不是系统的真实行为。 对于流式平均,最好应用 DSP.filt(averaging_filter, y_fir) 具有保存状态。
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!("Амплитуда")
切换到 filt 我消除了剪切工件,图形现在反映了系统的真实行为,它还允许我们创建一个完全流处理系统,其中:
- FIR滤波器(样本窗口2)平滑平滑信号(虚线);
- 移动平均线(10个样本的窗口)现在正确处理整个信号而没有零;
- 由于两个过滤器都在有状态流模式下运行,因此过滤器之间的相移已变得可预测。
结论
该示例清楚地演示了组合方法的优点,其中EngeeDSP系统对象用于流处理,而传统函数用于额外的转换。 最终的图表特别具有指示性,它允许您跟踪模型每个阶段的信号变化。 将Engee系统对象与传统的Julia方法相结合,为创建高效灵活的信号处理系统开辟了广泛的可能性。

