Applying DSP Library Filters
To demonstrate the different types of filters from the DSP library, we have prepared brief descriptions of each filter with an application example.
Here we will look at the basic filters.:
- Filters with finite impulse response,
- Low-pass filters,
- High-frequency filters.
You can learn more about all the principles of building filters in this example: https://engee.com/community/ru/catalogs/projects/sravnitelnyi-analiz-filtrov
Let's start by connecting this library. It is important to note that the DSP library distinguishes between filter coefficients and stateful filters.
Pkg.add("DSP")
using DSP
using FFTW
We will announce the input signal, which we will later use to test our filters.
We will also declare an auxiliary function.
Fs = 1000 # Частота дискретизации
t = 0:1/Fs:1-1/Fs # Временной интервал
x = sin.(2π .* 0.1 .* t) .+ randn(length(t)) # Сигнал с шумом (0.1 Гц компонент и шум)
plot(x)
# Расчёт спектра сигнала
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
spectrum_x, freqs_x = compute_spectrum(x, Fs)
plot(freqs_x, spectrum_x, xlabel="Frequency (Hz)", ylabel="Amplitude", legend=:topright)
Next, let's look at examples of the implementation of various filters.
FIR filters (Finite Impulse Response)
FIR filters have a finite pulse response, which makes them stably solvable and easy to design. They have no internal feedbacks.
The type of filter we use is a low-pass filter with a cutoff frequency of 5 Hz. It is applied to the signal using a FIR filter designed by the Hanning window method with a length of 64.
responsetype = Lowpass(5)
designmethod = FIRWindow(hanning(64))
y = filt(digitalfilter(responsetype, designmethod; fs=Fs), x)
plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
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")
After filtering, the signal became smoothed, suppressing the noise components. The waveform now better reflects the low-frequency component.
Peak noise emissions have practically disappeared, which confirms good filtering of high-frequency components.
Frequencies above 32 Hz are completely suppressed. The main amplitudes of the spectrum are concentrated at frequencies of 0 Hz (DC component) and 3 Hz.
This indicates that the filter has effectively suppressed noise above the cutoff frequency.
Low-pass filters
These filters pass signals with frequencies below a set threshold and attenuate signals with higher frequencies.
The type of filter we use is a low–pass filter with a cutoff frequency of 0.2 Hz. Designed by the 4th order elliptical filter method with tolerance deviations of 0.5 dB in the passband and 30 dB in the barrier band.
It is implemented as a transfer function using a polynomial representation (Polynomial Ratio).
responsetype = Lowpass(0.2)
designmethod = Elliptic(4, 0.5, 30)
tf = convert(PolynomialRatio, digitalfilter(responsetype, designmethod))
numerator_coefs = coefb(tf)
denominator_coefs = coefa(tf)
y = filt(tf, x)
plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
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")
The filter coped with the task worse than the previous one, as residual noise is visible in the main signal. There is smoothing, but its quality is unsatisfactory, as interference continues to have a significant impact on the final result.
The spectrum of the processed signal shows the presence of peaks at frequencies up to 130 Hz, which indicates insufficient filtering of high-frequency components: the filter inefficiently suppresses frequencies above its cutoff frequency.
Elliptical filters have a high steepness of the transition characteristic, but they can suffer from significant ripples in the bandwidth, which is observed in this case.
The cutoff frequency (0.2 Hz) and the selected filter parameters may not be optimal for this signal. In addition, the filter order (4th) may not be sufficient to achieve the required interference suppression.
High-pass filters
These filters pass signals with frequencies above a set threshold and attenuate signals with lower frequencies.
The type of filter that we have applied here is a High-pass filter with a cutoff frequency of 40 Hz, implemented using a 4th-order Butterworth filter.
responsetype = Highpass(40) # Высокочастотный фильтр, отсечка на 40 Гц, fs = 1000 Гц
designmethod = Butterworth(4) # Баттерворт, порядок 4
highpass_filter = digitalfilter(responsetype, designmethod; fs=Fs)
y = filt(highpass_filter, x) # Применяем фильтр к сигналу x
plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
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")
After filtering, the signal practically does not differ from the noisy original one, and this indicates that the low-frequency information determining the main fluctuations of the signal has been completely deleted.
The spectrum shows that all frequencies up to 40 Hz (including significant low-frequency components up to 24 Hz) are completely suppressed. This led to the loss of basic information about the signal, leaving only high-frequency noise.
A high-pass filter with a 40 Hz cutoff is completely unsuitable for analyzing this signal, since the significant frequency of the signal (0.1 Hz) lies in the range of low frequencies that the filter removes.
Band-pass filters
These filters pass signals within a given frequency band, attenuating signals outside that band.
The type of filter that we use here is a band–pass filter with a bandwidth from 10 to 40 Hz, implemented using a 4th-order Butterworth filter.
Sampling rate: 1000 Hz.
responsetype = Bandpass(10, 40)
designmethod = Butterworth(4)
y = filt(digitalfilter(responsetype, designmethod; fs=Fs), x)
plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
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")
The filter has smoothed out the noise, which is noticeable when comparing the processed signal with the original noisy one. However, useful information about the low-frequency fluctuations of the signal has been lost. There is only a "fragment" of the high-frequency part of the signal, which does not carry significant information.
The spectrum of the processed signal shows that the filter effectively suppressed frequencies below 10 Hz and above 70 Hz, but retained the range from 10 to 40 Hz, which in this case does not contain useful information. This led to the fact that the signal was represented by noise components in this band, having lost its original low-frequency character.
Band-stop filters
These filters attenuate signals in a given frequency range, skipping all other frequencies.
In this case, we are implementing a band-pass filter that suppresses frequencies in the range of 10-40 Hz and is implemented using a 4th-order Butterworth filter.
responsetype = Bandstop(10, 40) # Полосо-заградительный фильтр, подавляет частоты от 10 до 40 Гц, fs = 1000 Гц
designmethod = Butterworth(4) # Баттерворт, порядок 4
y = filt(digitalfilter(responsetype, designmethod; fs=Fs), x) # Применяем фильтр к сигналу x (определите x заранее)
plot(x, label="Original Signal", title="Signal")
plot!(y, label="Filtered Signal", xlabel="Sample", ylabel="Amplitude")
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")
After filtering, the signal looks almost the same as the original noisy one, which indicates a slight effect of the filter on the visible structure of the signal.
The spectrum shows frequency suppression in the range from 12 to 32 Hz. The remaining frequency components, including noise, remained virtually unchanged.
This explains the continued noisy nature of the signal.
Conclusion
We looked at various filters for solving this problem and found out that the FIR filter with a Hanning window turned out to be the best choice. Its ability to smoothly and effectively remove noise above a given cutoff frequency allowed it to isolate useful low-frequency information (0.1 Hz), which was the main task.
Summarizing the comparisons you have made, we can draw the following conclusion: for such tasks, it is worth using low-pass filters with a cutoff frequency that optimally corresponds to the range of useful information.