Need Help about FFT and STFT
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
0 개 추천
Hi!
I got a large amount of data, more than 5mb, so I can’t upload it. I would like to ask, my data is three xyz three-axis data collected from acceleratoter and it based on time, they are written in a .mat file.
I want to intercept a small part of the time from this .mat file. What should I do?
After that when i get the new data from that time ,how can i calculate the FFT Power Spectrum for a sliding window ? Can someone help me with this? Best Regards!
채택된 답변
Mathieu NOE
2021년 1월 13일
hello
see the code below for (averaged) fft analysis and spectrogram
you can easily incorporate a test to select samples that matches the condition time > t_min and time < t_max.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
load('signal15.mat') % time (tout) and data (simout)
% t = tout;
channel = 1;
signal = simout(:,channel);
samples = length(signal);
Fs = 1/mean(diff(tout));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% FFT parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
NFFT = 4096; %
OVERLAP = 0.75;
% spectrogram dB scale
spectrogram_dB_scale = 80; % dB range scale (means , the lowest displayed level is XX dB below the max level)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% options
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if you are dealing with acoustics, you may wish to have A weighted
% spectrums
% option_w = 0 : linear spectrum (no weighting dB (L) )
% option_w = 1 : A weighted spectrum (dB (A) )
option_w = 0;
%% decimate (if needed)
% NB : decim = 1 will do nothing (output = input)
decim = 2;
if decim>1
signal = decimate(signal,decim);
Fs = Fs/decim;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 1 : averaged FFT spectrum
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[freq, sensor_spectrum] = myfft_peak(signal,Fs,NFFT,OVERLAP);
% convert to dB scale (ref = 1)
sensor_spectrum_dB = 20*log10(sensor_spectrum);
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(freq);
sensor_spectrum_dB = sensor_spectrum_dB+pondA_dB;
my_ylabel = ('Amplitude (dB (A))');
else
my_ylabel = ('Amplitude (dB (L))');
end
figure(1),plot(freq,sensor_spectrum_dB,'b');grid
title(['Averaged FFT Spectrum / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(freq(2)-freq(1)) ' Hz ']);
xlabel('Frequency (Hz)');ylabel(my_ylabel);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display 2 : time / frequency analysis : spectrogram demo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[sg,fsg,tsg] = specgram(signal,NFFT,Fs,hanning(NFFT),floor(NFFT*OVERLAP));
% FFT normalisation and conversion amplitude from linear to dB (peak)
sg_dBpeak = 20*log10(abs(sg))+20*log10(2/length(fsg)); % NB : X=fft(x.*hanning(N))*4/N; % hanning only
% apply A weigthing if needed
if option_w == 1
pondA_dB = pondA_function(fsg);
sg_dBpeak = sg_dBpeak+(pondA_dB*ones(1,size(sg_dBpeak,2)));
my_title = ('Spectrogram (dB (A))');
else
my_title = ('Spectrogram (dB (L))');
end
% saturation of the dB range :
% saturation_dB = 60; % dB range scale (means , the lowest displayed level is XX dB below the max level)
min_disp_dB = round(max(max(sg_dBpeak))) - spectrogram_dB_scale;
sg_dBpeak(sg_dBpeak<min_disp_dB) = min_disp_dB;
% plots spectrogram
figure(2);
imagesc(tsg,fsg,sg_dBpeak);colormap('jet');
axis('xy');colorbar('vert');grid
title([my_title ' / Fs = ' num2str(Fs) ' Hz / Delta f = ' num2str(fsg(2)-fsg(1)) ' Hz ']);
xlabel('Time (s)');ylabel('Frequency (Hz)');
function pondA_dB = pondA_function(f)
% dB (A) weighting curve
n = ((12200^2*f.^4)./((f.^2+20.6^2).*(f.^2+12200^2).*sqrt(f.^2+107.7^2).*sqrt(f.^2+737.9^2)));
r = ((12200^2*1000.^4)./((1000.^2+20.6^2).*(1000.^2+12200^2).*sqrt(1000.^2+107.7^2).*sqrt(1000.^2+737.9^2))) * ones(size(f));
pondA = n./r;
pondA_dB = 20*log10(pondA(:));
end
function [freq_vector,fft_spectrum] = myfft_peak(signal, Fs, nfft, Overlap)
% FFT peak spectrum of signal (example sinus amplitude 1 = 0 dB after fft).
% Linear averaging
% signal - input signal,
% Fs - Sampling frequency (Hz).
% nfft - FFT window size
% Overlap - buffer overlap % (between 0 and 0.95)
signal = signal(:);
samples = length(signal);
% fill signal with zeros if its length is lower than nfft
if samples<nfft
s_tmp = zeros(nfft,1);
s_tmp((1:samples)) = signal;
signal = s_tmp;
samples = nfft;
end
% window : hanning
window = hanning(nfft);
window = window(:);
% compute fft with overlap
offset = fix((1-Overlap)*nfft);
spectnum = 1+ fix((samples-nfft)/offset); % Number of windows
% % for info is equivalent to :
% noverlap = Overlap*nfft;
% spectnum = fix((samples-noverlap)/(nfft-noverlap)); % Number of windows
% main loop
fft_spectrum = 0;
for i=1:spectnum
start = (i-1)*offset;
sw = signal((1+start):(start+nfft)).*window;
fft_spectrum = fft_spectrum + (abs(fft(sw))*4/nfft); % X=fft(x.*hanning(N))*4/N; % hanning only
end
fft_spectrum = fft_spectrum/spectnum; % to do linear averaging scaling
% one sidded fft spectrum % Select first half
if rem(nfft,2) % nfft odd
select = (1:(nfft+1)/2)';
else
select = (1:nfft/2+1)';
end
fft_spectrum = fft_spectrum(select);
freq_vector = (select - 1)*Fs/nfft;
end
댓글 수: 5
Thanks for your Answer. I would like to ask. I have finisched(below) the step of calculate the fft windows. Now i want to calculate the average, the mean of all windows. What should i do?
clc;clear all;close all;
load('UPDRS_ACC_DATA.mat')
time_vec = 1/Fs:1/Fs:size(ACC_DATA_R,2)/Fs;
time_postural_tremor = 103050:1:151900; % second 25-37
xL = ACC_DATA_L(:,time_postural_tremor)';
xR = ACC_DATA_R(:,time_postural_tremor);
%caculate fft with window
%left
windowsize = Fs*2; %because the window is 2s , and sample frequncy is 4096, so it is the size
window = hamming(windowsize);
nfft = windowsize; %equal to window size
noverlap = Fs; % overlap is 1s,so it is Fs
xL1 = ACC_DATA_L(3,time_postural_tremor);%tremor data is z axis used
[S1,F1,T1] = spectrogram(xL1,window,noverlap,nfft,Fs);
imagesc(T1, F1, 20*log10((abs(S1))));xlabel('Time in S LEFT'); ylabel('Freqency');
colorbar;
%right
windowsize = Fs*2; %because the window is 2s , and sample frequncy is 4096, so it is the size
window = hamming(windowsize);
nfft = windowsize; %equal to window size
noverlap = Fs; % overlap is 1s,so it is Fs
xR1 = ACC_DATA_R(3,time_postural_tremor);%tremor data is z axis used
[S2,F2,T2] = spectrogram(xR1,window,noverlap,nfft,Fs);
figure;
imagesc(T2, F2, 20*log10((abs(S2))));xlabel('Time in s RIGHT'); ylabel('Freqency');
colorbar;
%why i can not show the right and left spectrum the same time?as you see it
%is only right
% Answer: you need to open new "figure" (I added it in line 30); otherwise the plot
% is overwritten
figure
% raw data
subplot(2,1,1);
plot(time_vec(time_postural_tremor), xL);
title('Postural Tremor LEFT')
ylabel('Acceleration (raw data)')
xlabel('Time in s')
xlim([time_vec(time_postural_tremor(1)) time_vec(time_postural_tremor(end))])
legend({'x','y','z'})
grid on
subplot(2,1,2);
plot(time_vec(time_postural_tremor), xR);
title('Postural Tremor RIGHT')
ylabel('Acceleration (raw data)')
xlabel('Time in s')
xlim([time_vec(time_postural_tremor(1)) time_vec(time_postural_tremor(end))])
legend({'x','y','z'})
grid on
Mathieu NOE
2021년 1월 13일
hello
for example , you can average S1 along the time axis to get only a vector , that must have the same length as F1.
Xiaoming Hu
2021년 1월 15일
thanks ! one more question:
will the window lengths and overlaps influences the outcome ? How can i select a good size of window?
Mathieu NOE
2021년 1월 18일
hello
If your window lenghth is nfft , the spectrum frequency resolution is df = Fs/nfft ; so there are compromise between frequency resolution and time resolution for a spectrogram plot.
I usually start with an overlap of 50 to 75% of nfft .
if I really need to heave a smoother and refined time resolution , I can go up to 95 / 97% of overlap.
Xiaoming Hu
2021년 1월 22일
편집: Xiaoming Hu
2021년 1월 22일
Thanks Professor!!! HHH,
I have finisch the nfft and i just get the area what i want to use from 0.9hz to 15hz. Then i want to get a root mean square value. The code what i have did till right now is below.
windowsize = Fs*2; %because the window is 2s , and sample frequncy is 4096, so it is the size
window = hamming(windowsize);
nfft = windowsize; %equal to window size
noverlap = Fs; % overlap is 1s,so it is Fs
xR2 = ACC_DATA_R(3,time_postural_tremor);%tremor data is z axis used
[S2,F2,T2,P2] = spectrogram(xR2,window,noverlap,nfft,Fs);%%this is for calculate the average power
f_bigger_09Hz = find(F2>0.9,1,'first');
f_15Hz = find(F2<=15,1,'last');
%Right
figure;
plot(F2(f_bigger_09Hz:f_15Hz),P2(f_bigger_09Hz:f_15Hz,:))
ylabel('power')
xlabel('Frequency in Hz right')
grid on
%Left
figure;
plot(F1(f_bigger_09Hz:f_15Hz),P1(f_bigger_09Hz:f_15Hz,:))
ylabel('power')
xlabel('Frequency in Hz left')
grid on %% iget the area what i need(0.9hz to 15h
Can u give me a help how to calculate this area to get a root mean square value?
Thanks!
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Spectral Measurements에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
