AnyMath 文档
Notebook

数字滤波器编辑器

在本例中,我们将分析使用基于预先描述的噪声信号的数字滤波器编辑器应用程序并对其应用有限脉冲响应滤波的原理。

让我们声明我们在这项工作中需要的辅助功能。:

  1. 用于解析由数字滤波器编辑器生成的系数的函数;
  2. 用于计算信号频谱的辅助功能。
In [ ]:
Pkg.add(["DSP"])
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
using DSP, FFTW

function read_coeff(path)
    # 阅读TXT
    txt = open(io->read(io, String), path)
    # 用逗号替换\n并将字符串包装在[]中
    data_str = "[" * replace(txt, "\n" => ",") * "]"
    # 将字符串转换为表达式
    parsed_expr = Meta.parse(data_str)
    # 我们执行表达式得到向量
    data_vector = eval(parsed_expr)
    return data_vector
end

function compute_spectrum(signal, fs)
    n = length(signal)
    spectrum = abs.(fft(signal)) / n
    freqs = (0:n-1) .* (fs / n)
    spectrum[1:Int(n/2)], freqs[1:Int(n/2)]  # 返回频谱的一半(为方便起见)
end
Out[0]:
compute_spectrum (generic function with 1 method)

现在让我们继续定义输入信号并对其进行分析,前提是采样频率为1MHz。

In [ ]:
Fs = 1000  # 采样率
t = 0:1/Fs:1-1/Fs  # 时间间隔
x = sin.(2π .* 0.1 .* t) .+ randn(length(t))  # 噪声信号(0.1Hz分量和噪声)

spectrum_x, freqs_x = compute_spectrum(x, Fs)
plot(freqs_x, spectrum_x, xlabel="Frequency (Hz)", ylabel="Amplitude", legend=:topright)
Out[0]:

分析信号的频谱,我们在0Hz处看到一个峰值。 段频谱中振幅峰值的存在表明存在强谐波分量。

要滤除除峰值频率之外的所有频率,滤波器的幅频响应(频率响应)必须平坦到截止频率,然后对于所有其他频率急剧减小到无穷小值。

这可以使用低通滤波器来实现。 在这种情况下,我们使用窗口FIR滤波器。 在这里,我们需要使用数字滤波器编辑器应用程序计算该滤波器的系数。

下面是生成系数的示例。

生成后,我们下载文件,然后用系数解析文件。 此外,值得关注的事实是,滤波器的分母由等于一的系数设置,这允许它们被丢弃。

Снимок экрана 2024-12-17 142613.png Снимок экрана 2024-12-17 142637.png

让我们从生成的TXT文件下载系数。

In [ ]:
bat_num = read_coeff("$(@__DIR__)/num_coeff.txt")
Out[0]:
11-element Vector{Float64}:
 0.08670710125932124
 0.08919851935658485
 0.0911692583414991
 0.0925947918347827
 0.09345731482134326
 0.09374602877293467
 0.09345731482134309
 0.09259479183478204
 0.09116925834149865
 0.08919851935658467
 0.0867071012593207

现在我们将使用先前计算的系数声明一个窗口化FIR滤波器。

In [ ]:
responsetype = Lowpass(5)
designmethod = FIRWindow(bat_num)
Out[0]:
FIRWindow{Float64}([0.08670710125932124, 0.08919851935658485, 0.0911692583414991, 0.0925947918347827, 0.09345731482134326, 0.09374602877293467, 0.09345731482134309, 0.09259479183478204, 0.09116925834149865, 0.08919851935658467, 0.0867071012593207], true)

让我们对信号进行滤波,并比较信号本身和频谱的输入和输出值。

In [ ]:
y = filt(digitalfilter(responsetype, designmethod; fs=Fs), x)

plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
Out[0]:

经过滤波后,信号变得平滑,抑制了噪声成分。 信号的形状现在更好地反映了信号行为的总体趋势。

峰值噪声发射实际上已经消失,这证实了高频分量的成功滤波。

In [ ]:
spectrum_y, freqs_y = compute_spectrum(y, Fs)

plot(freqs_x, spectrum_x, label="Original Signal Spectrum", xlabel="Frequency (Hz)", ylabel="Amplitude", legend=:topright)
plot!(freqs_y, spectrum_y, label="Filtered Signal Spectrum", title="Signal Spectrum")
Out[0]:

65Hz以上的频率被完全抑制。 频谱的主要振幅集中在0Hz的频率处。 这表明滤波器有效地抑制了截止频率以上的噪声,并允许有用的源信号被隔离。

结论

在这个例子中,演示了交互式Engee脚本中的信号过滤功能以及使用附加环境应用程序数字滤波器编辑器的方法。 我们已经确保使用这些工具正确执行分配的任务。