初めに
アナログ回路のローパスフィルタとフーリエ変換の関係において以下の点ついてまとめる。
- サンプリング周波数より高い周波数の信号が存在する場合、フーリエ変換後にその成分が乗ってくる。よってAD変換する前にローパスフィルタを挟む必要がある。
- サンプリング周波数より高い周波数の波形成分は、フーリエ変換後に分離できない。
一般的に教科書では天下り的にサンプリング定理やエイリアシングに触れるが、実際にどのように効くのか説明されないのでまとめる。また数式を追う事はしない。
どこで、この記事の知識が使えるか
IoTシステムやエッジAIシステム?、クラウドシステム?
ビックデータの時代とは言っても資源(サーバなど)は有限であり、データを軽くするために低周波サンプリングをしたがる人はいるのかもしれない。
基本的なフーリエ変換の復習だと思っていただければ幸いである。
サンプリング周波数より高い周波数の信号
サンプリング周波数より高い周波数の信号が存在する場合、フーリエ変換後にその成分が低周波に現れる。また、初めに
にて記述した通り、数式的な説明は行わない。
周波数110 Hz
、振幅を1
とするsin波をサンプリング周波数を100 Hz
にて計測する。そして計測された波形をフーリエ変換する。ここでは、ファンクションジェネレータを用いるなど電子回路的に行うのではなく、pythonで簡易的に再現する。
import numpy as np
import matplotlib.pyplot as plt
# サンプリング周波数
fs = 100
# 時間軸の設定
t = np.arange(0, 1, 1/fs)
# 110 Hzの正弦波信号を生成
f1 = 110
x = np.sin(2*np.pi*f1*t)
# フーリエ変換
X = np.fft.fft(x)
# 周波数軸の設定
freq = np.fft.fftfreq(len(x), d=1/fs)
# 周波数スペクトルのプロット
plt.plot(freq, np.abs(X/(len(t)/2)))
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude')
plt.xlim(0, fs/2)
plt.grid()
plt.show()
横軸Frequnecy [Hz]
において10 Hz
で縦軸Amplitude
が1
になっている。フーリエ変換前に使用した波形は110 Hz
のsin波であり、望ましい結果ではない。
このようにサンプリング周波数より高周波の信号は、低周波側の信号とみなされてしまう(エイリアシング)。上の出力結果から見て分かる通り、周波数10 Hz
、振幅1
の波形と区別できない。
よって、AD変換する前にナイキスト周波数(サンプリング周波数の半分)より高い周波数で、サンプリング周波数より低い周波数にカットオフ周波数が存在するアナログ回路のローパスフィルタを入れるのが良い。
サンプリング周波数を高くして計測し、AD変換して、フーリエ変換して、高周波成分の振幅を0
にすればいいと主張する人がいるかもしれないが、AD変換の時点でナイキスト周波数以上の波形成分はナイキスト周波数以下の波形成分と混じってしまう。影響の大きさは、ケースバイケースだが、入手した信号が正確なものであるという保証はされない。
ローパスフィルタのカットオフ周波数はどこがベストかについては匙加減だと思っています。(すいません
結論
センサデータなど波形を計測する際にはアナログ回路のローパスフィルタを使用すべき。