web-dev-qa-db-ja.com

MATLABの信号データから周波数を決定する

センサーからのデータがあり、その頻度を見つける必要があります。 fft()が方法のように見えますが、MATLABのドキュメントでは、周波数のグラフを取得する方法のみが示されており、そこから何をすべきかわかりません。

データは次のようになります。

enter image description here

14
edc1591

実際に行う方法の1つは、fftを使用することです。 fftは信号の周波数表現を提供するため、最大値を探す必要があります。また、fftは複素信号なので、絶対値を最初に取得する必要があります。インデックスは、最大エネルギーの正規化された周波数に対応します。最後に、表示する信号のように信号にオフセットがある場合は、DCコンポーネント。

私が説明したものはすべて1行になります。

[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));

ここで、indexMaxは最大fft値を見つけることができるインデックスです。

注:indexMaxから目的の実際の周波数に到達するには、fftの長さL(信号の長さと同じ)とサンプリング周波数Fsを知る必要があります。信号周波数は次のようになります。

frequency = indexMax * Fs / L;

あるいは、より速く、かなりうまく機能している信号にもよりますが、信号の自己相関を取ります:

autocorrelation = xcorr(signal);

自己相関の中心点の後に発生する最初の最大値を見つけます。 (自己相関は対称であり、その最大値は中央にあります。)その最大値を見つけることにより、シフトされた信号が多かれ少なかれそれ自身のように見える最初の場所を見つけます。つまり信号の周期を見つけます。周期の倍数だけシフトされた信号は常にそれ自体のように見えるため、見つけた最大値が実際にその倍数の1つではなく信号の周期に対応することを確認する必要があります。

信号のノイズのため、絶対最大値は、周期そのものではなく、周期の倍数で非常によく発生する可能性があります。したがって、そのノイズを考慮するには、自己相関の絶対最大値(autocorrelation(length(autocorrelation)/ 2 + 1)を取得し、最初の最大値の95%など、自己相関がどこで大きいかを見つけます。信号の後半の時間95%、99%、またはその他の数値は、ノイズがどれだけ信号を破壊するかに依存します。

更新:私はあなたがあなたの信号の「周波数」によってピッチまたはベースの倍音または最もエネルギーの高い周波数を意味していると思いますが、あなたはそれを見たいと思います。周波数で信号の周波数表現を意味する場合、最初の近似値まで、FFTのabsをプロットして、エネルギーがどこにあるかを把握します。

plot(abs(fft));

Absが存在する理由や、fftのフェーズを表さないことで失われている関連情報を理解したい場合は、DFT変換についてもう少し読んで、得られるものを正確に理解することができます。

18
Lolo

私はそれがあるべきだと思う

 (indexMax-1) * Fs / L 

Abs(fft(x))の最初の要素は、直流(DC)、バイアス、または信号の平均、またはX0です。 2番目の要素(X1)からカウントします。私が間違っているかどうか教えてください。ありがとう。 enter image description here

clear all
clc
close all
Fs = 1;
T = 11 % Note this T is deliberately chosen , so that we have about 1.7 cycle of cosine singal
t = 0:Fs:T; % T seconds
L = length(t); % L is the length of sample sequence
bias = 4
signal = sin(t) + bias;

[maxValue,indexMax] = max(abs(fft(signal-mean(signal))));

frequency_method1 = (indexMax-1) * Fs / (L-1);
frequency_method2 = (indexMax-1) * Fs / L;


number_of_cycles_method1 = frequency_method1*T

number_of_cycles_method2 = frequency_method2*T


subplot(2,1,1)
plot(t,signal,'-or') ; grid on;
legend('about 1.7 cycles of cosine signal')
subplot(2,1,2)
plot(abs(fft(signal-mean(signal))),'-xb'); grid on
legend('abs of fft')

number_of_cycles_method1 =

     2


number_of_cycles_method2 =

    1.8333