How can I filter a FFt signal to only show the main frequency?
Ältere Kommentare anzeigen
I have the following code (a sample data file is attached).
load("sample_signal.mat");
whos
figure
subplot(2,1,1)
hold on; grid minor
plot(signals.signal_01.signal)
plot(signals.signal_02.signal)
plot(signals.signal_03.time, signals.signal_03.theta, 'k')
title("Signal");
subplot(2,1,2)
hold on; grid minor
fs = 1;
[freq, amplitude, phase] = generic_fft(signals.signal_01.signal, fs);
plot(freq, amplitude)
[freq, amplitude, phase] = generic_fft(signals.signal_02.signal, fs);
plot(freq, amplitude)
fs = 10;
[freq, amplitude, phase] = generic_fft(signals.signal_03.theta, fs);
plot(freq, amplitude, 'k')
xlim([0 0.5])
xlabel("$\omega$ [rad/s]")
ylabel("fft")
title("FFT");
% fft function
function [freq, amplitude, phase] = generic_fft(signal, fs)
% Remove NaNs
signal = signal(~isnan(signal));
% Length of the signal
n = length(signal);
% Perform FFT
fft_values = fft(signal);
% Compute single-sided amplitude spectrum
amplitude = abs(fft_values / n); % Normalize by length
amplitude = amplitude(1:floor(n / 2) + 1); % Keep positive frequencies
amplitude(2:end-1) = 2 * amplitude(2:end-1);
% Compute single-sided phase spectrum
phase = angle(fft_values(1:floor(n / 2) + 1));
% Frequency vector
freq = (0:(n / 2)) * (fs / n);
end
Now, the signal plotted in black shows a clear, dominant frequency in the FFt, but the other two signals show additional "noise" (see, after 0.1 rad/s). Is it possible to maybe filter these out or only show the dominant frequency?
EDIT : What I wanted is not to identify one frequency point, but rather something similar to the black line in the fft plot. I.e., the signals used would need to be smoothened maybe?
The code is rough and the data structure is also not ideal (I saved the data mid-simulation for this question :) ). Also, any tips to improve the fft function is also very appreciated. TIA!
5 Kommentare
Walter Roberson
am 9 Jan. 2025
In an FFT plot, showing only the dominent frequency would be a pulse plot -- everything zero except for a single point.
dpb
am 9 Jan. 2025
Averaging will reduce any random components leaving the deterministic signals cleaner.
Jake
am 10 Jan. 2025
dpb
am 10 Jan. 2025
"... I did try using a simple smooth command to smooth the signal before getting the fft, ..."
Compute the PSD by averaging over sections of the signal to reduce stochastic noise in the result.
Subtract the mean or detrend to remove the DC component first...
Walter Roberson
am 10 Jan. 2025
It depends on the shape of your noise. For "salt and pepper" noise (gaussian noise), just zero some of the high frequency bins of the fft: gaussian noise is equivalent to adding a high frequency.
This will not have the effect of smoothing your fft output. Smoothing your fft output is equivalent to removing noise that is frequency-dependent.
Akzeptierte Antwort
Weitere Antworten (1)
Walter Roberson
am 9 Jan. 2025
[~, maxidx] = max(abs(amplitude));
main_signal = zeros(size(amplitude));
main_signal(maxidx) = amplitude(maxidx);
Do not be surprised if the peak frequency is maxidx == 1, corresponding to 0 Hz.
Kategorien
Mehr zu Spectral Measurements finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


