Python言語とNumPyを用いて、高速逆フーリエ変換とローパス処理を行い、ノイズを取り出す方法をソースコード付きで解説します。
## 【フーリエ変換】ハイパスフィルタでノイズ除去(正弦波のみ)
Python + NumPyでフーリエ変換によるハイパスフィルタ処理(高周波ノイズ抽出)を実装してみます。
今回実装したプログラムの処理手順は以下の通りです。
| – | 処理手順 |
|---|---|
| ① | 時間信号(周波数5の正弦波 + 周波数40の正弦波)を生成します。 |
| ② | 高速フーリエ変換により、時間信号を周波数信号に変換します。 |
| ③ | カットオフ周波数fc未満の帯域と、右半分の帯域の周波数信号を0にします。 |
| ④ | 高速逆フーリエ変換により、周波数信号を時間信号に変換します。 |
| ⑤ | 処理結果をグラフに表示します。 |
## 【サンプルコード】Python + NumPy
サンプルプログラムのソースコードです。
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
def main():
# データのパラメータ
N = 256 # サンプル数
dt = 0.01 # サンプリング間隔
fq1, fq2 = 5, 40 # 周波数
fc = 20 # カットオフ周波数
t = np.arange(0, N*dt, dt) # 時間軸
freq = np.linspace(0, 1.0/dt, N) # 周波数軸
# 時間信号(周波数5の正弦波 + 周波数40の正弦波)の生成
f = np.sin(2*np.pi*fq1*t) + 0.5 * np.sin(2*np.pi*fq2*t)
# 高速フーリエ変換(周波数信号に変換)
F = np.fft.fft(f)
# 正規化 + 交流成分2倍
F = F/(N/2)
F[0] = F[0]/2
# 配列Fをコピー
F2 = F.copy()
# ハイパス処理(カットオフ周波数未満の帯域と、右半分の帯域の周波数信号を0にする)
F2[(freq < fc)] = 0
F2[(freq > 1/(dt*2))] = 0
# 高速逆フーリエ変換(時間信号に戻す)
f2 = np.fft.ifft(F2)
# 振幅を元のスケールに戻す
f2 = np.real(f2*N)
# グラフ表示
plt.figure()
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['font.size'] = 17
# 時間信号(元)
plt.subplot(221)
plt.plot(t, f, label='f(n)')
plt.xlabel("Time", fontsize=20)
plt.ylabel("Signal", fontsize=20)
plt.grid()
leg = plt.legend(loc=1, fontsize=25)
leg.get_frame().set_alpha(1)
# 周波数信号(元)
plt.subplot(222)
plt.plot(freq, np.abs(F), label='|F(k)|')
plt.xlabel('Frequency', fontsize=20)
plt.ylabel('Amplitude', fontsize=20)
plt.grid()
leg = plt.legend(loc=1, fontsize=25)
leg.get_frame().set_alpha(1)
# 時間信号(ハイパス処理後)
plt.subplot(223)
plt.plot(t, f2, label='f2(n)')
plt.xlabel("Time", fontsize=20)
plt.ylabel("Signal", fontsize=20)
plt.grid()
leg = plt.legend(loc=1, fontsize=25)
leg.get_frame().set_alpha(1)
# 周波数信号(ハイパス処理後)
plt.subplot(224)
plt.plot(freq, np.abs(F2), label='|F2(k)|')
plt.xlabel('Frequency', fontsize=20)
plt.ylabel('Amplitude', fontsize=20)
plt.grid()
leg = plt.legend(loc=1, fontsize=25)
leg.get_frame().set_alpha(1)
plt.show()
if __name__ == "__main__":
main()
実行結果
サンプルプログラム実行結果です。

上が「処理前の時間信号・周波数信号」、下が「処理後の時間信号・周波数信号」です。
カットオフ周波数20でハイパスフィルタ処理しているので、高周波成分(周波数40の正弦波)がうまく抽出できていることがわかります。


コメント