スポンサーリンク
fftと窓関数の関係についてざっくりと説明します。
ざっくりなので、専門家には指摘したい箇所があると思いますが、実用上は下記の理解で困らないと思うので、大目に見てください。
はじめに
fftでは、信号が周期的であることを仮定し(その信号がずっと続くことを仮定)、その信号の周波数を分析します。長時間の信号を周波数分析することは、分析コスト(処理時間や負荷)が大きいので、信号を短く切り出します。
短く切り出したとしても、周期的であることを仮定しているので、この短く切り出した信号がループ再生していると考えても同じことになります。(信号がノイズの音源ファイルだとして、短い時間で切り出した音源を音楽プレイヤーなどでループ再生しても同じでしょ?という考えです。)
ただし、短く切り出したデータが下図のような場合、どうなるでしょうか?
この信号がずっと続くことを仮定した場合、下図のようになってしまいます。
すこしわかりにくいですが、x軸の1000と2000のところで信号が不連続になっていることがわかります。不連続になることで、fft結果に信号にはない周波数成分が含まれてしまいます。これをリーケージ誤差もしくは漏れ誤差と呼びます。
スポンサーリンク
窓関数
これを避けるためにあらかじめ、信号のはじめと端部を0にしておこう!というのが窓関数の考えです。
下図が一般的に使用される窓関数です。窓関数にも種類があり、用途によって使い分けられますが、ハンマリングでは方形波窓(レクタンギュラ窓)を使用し、その他ではハニング窓が良く使用されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | clear all smplingFreq=1024; time=linspace(0,1,smplingFreq); hannWin = max(0.5*ones(1,smplingFreq) - 0.5*cos(2.0*pi*time),eps); hammWin = 0.54*ones(1,smplingFreq) - 0.46*cos(2.0*pi*time); rectanWin = ones(1,smplingFreq); blackmanWin = max(0.42*ones(1,smplingFreq) - 0.5*cos(2.0*pi*time) + 0.08*cos(4.0*pi*time),eps); figure subplot(411) plot(hannWin, 'r' , 'linewidth' ,3) xlim([1 1024]) title( 'ハニング窓' ) subplot(412) plot(hammWin, 'r' , 'linewidth' ,3) xlim([1 1024]) title( 'ハミング窓' ) subplot(413) plot(rectanWin, 'r' , 'linewidth' ,3) xlim([1 1024]) title( '方形波窓' ) subplot(414) plot(blackmanWin, 'r' , 'linewidth' ,3) xlim([1 1024]) title( 'ブラックマン窓' ) |
窓関数を適用すると、信号は下図のようになります。この短い波形を繰り返しつなげたとしても波形が不連続になることはありません。ただし、窓関数を適用したことで、振幅が小さくなってしまっています。そのため、窓関数を適用した場合はfft結果を補正する必要があります。補正の方法は後日まとめたいと思います。
スポンサーリンク
1 2 3 4 5 6 7 8 9 10 11 12 | clear all smplingFreq=1024; time=linspace(0,1,smplingFreq); hannWin = max(0.5*ones(1,smplingFreq) - 0.5*cos(2.0*pi*time),eps); y=sin(10*2*pi*time); figure plot(y.*hannWin, 'r' , 'linewidth' ,3) xlim([1 1024]) title( 'ハニング窓処理後' ) |
今回はこのへんでGood luck
コメント
最初のfttから気になる
誤字の指摘ありがとうございます。訂正いたしました。