FFTを用いた基本的な信号解析
この章では、NumPyを用いて基本的な信号解析を行う方法について解説します。具体的には、サンプル信号を生成し、FFTを実行してその結果を解釈し、さらに逆FFTを用いて信号を再構成する手順を示します。
サンプル信号の生成
まずは、解析対象となるサンプル信号を生成します。ここでは、異なる周波数成分を持つサイン波を組み合わせた信号を例にします。
コード例
import numpy as np
import matplotlib.pyplot as plt
# サンプリング設定
sampling_rate = 1000 # サンプリング周波数(Hz)
T = 1.0 / sampling_rate # サンプリング間隔
t = np.arange(0, 1.0, T) # 時間ベクトル
# 信号生成(50Hzと120Hzのサイン波を重ねたもの)
f1 = 50 # Hz
f2 = 120 # Hz
signal = np.sin(2 * np.pi * f1 * t) + 0.5 * np.sin(2 * np.pi * f2 * t)
# 信号のプロット
plt.figure(figsize=(12, 4))
plt.plot(t, signal)
plt.title('Sample Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.grid(True)
plt.show()
解説
- サンプリング周波数(sampling_rate): 信号をデジタル化する際のサンプリング頻度です。
- 時間ベクトル(t): 1秒間にわたる時間の配列を生成します。
- 信号の生成: 50 Hzと120 Hzの2つの異なる周波数成分を持つサイン波を重ねた信号を作成しました。
FFTの実行と結果の解釈
次に、生成した信号に対してFFTを実行し、周波数成分を解析します。
コード例
# FFT実行
fft_result = np.fft.fft(signal)
# 周波数軸の計算
freqs = np.fft.fftfreq(len(signal), T)
# FFT結果のプロット
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(t, signal)
plt.title('Original Signal')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.grid(True)
plt.subplot(2, 1, 2)
plt.stem(freqs[:len(freqs)//2], np.abs(fft_result)[:len(freqs)//2], 'b', markerfmt=" ", basefmt="-b")
plt.title('FFT Result')
plt.xlabel('Frequency (Hz)')
plt.ylabel('Magnitude')
plt.grid(True)
plt.tight_layout()
plt.show()
解説
-
FFTの実行:
np.fft.fft
を用いて信号のFFTを計算し、周波数領域での信号の大きさと位相を取得します。 -
周波数軸の計算:
np.fft.fftfreq
を使用して、FFTの結果に対応する周波数成分を計算します。 - 結果の解釈: プロットの下部には、信号に含まれる周波数のスペクトルが表示され、50 Hzと120 Hzのピークが確認できます。これは、信号がこれらの周波数成分を持つことを示しています。
逆FFTによる信号の再構成
FFTの結果を用いて、元の時間領域の信号を再構成します。これにより、FFTを用いた信号処理が正しく行われたことを確認できます。
コード例
# 逆FFT実行
ifft_result = np.fft.ifft(fft_result)
# 元の信号と再構築信号のプロット
plt.figure(figsize=(12, 4))
plt.plot(t, ifft_result.real)
plt.title('Reconstructed Signal from IFFT')
plt.xlabel('Time (s)')
plt.ylabel('Amplitude')
plt.grid(True)
plt.show()
解説
-
逆FFTの実行:
np.fft.ifft
を使用して、周波数領域のデータを時間領域に逆変換します。 - 信号の再構成: 再構成された信号をプロットすることで、元の信号と一致していることが確認できます。これにより、FFTおよび逆FFTの正確さを検証できます。
関連資料