本記事では、Python上でローパスフィルタを設計してFIRを適用して実際にフィルタをかけてみます。
FIRフィルタの実装は前回の記事を用いています。
あわせて読みたい


FIRフィルタ 【Python 音声音響信号処理】
本記事では、PythonでFIRフィルタを実装します。 FIRフィルタの構成 FIRフィルタは次式で定義されます。 $$y[n] = \sum_{i=0}^N b_i x[n-i]$$ ここで、\(b_i\)はi番目の...
目次
ローパスフィルタとは
ローパスフィルタとは、以下の図のように低周波成分のみ通過させ、高周波成分を遮断するというフィルタになります。
理想的なローパスフィルタは下図のように、通過帯域はゲインが1, 遮断帯域は0になります。

ローパスフィルタの係数を求める
上記の信号に対して逆フーリエ変換することで、ローパスフィルタの係数が得られます。理想的なローパスフィルタは矩形関数で表すことができ、矩形関数の逆フーリエ変換はsinc関数となります。
したがって、カットオフ周波数で矩形関数を定義し、それを逆フーリエ変換することでフィルタ係数を求めることができる。
しかし、sinc関数は無限の範囲で定義されているため、実際には有限長に打ち切ることが必要です。また、時刻が負の値の値を持っているため、因果性を満たすことはできません。
そこで、まずはシフトさせて0から信号、つまり係数データがはじまるようにします。
実装
from fir import Fir
import numpy as np
def make_low_pass_coeffs(cutoff_frequency, fs, num_taps=51):
# 周波数特性を作成
freq_response = np.zeros(num_taps)
# カットオフ周波数までを1にする
freq_bins = np.fft.fftfreq(num_taps, d=1/fs)
freq_response[np.abs(freq_bins) <= cutoff_frequency] = 1
# 逆フーリエ変換でインパルス応答を得る
h = np.fft.ifft(freq_response).real
# シフトして中央に配置
h = np.fft.fftshift(h)
# 正規化
h /= np.sum(h)
return h
if __name__ == "__main__":
import matplotlib.pyplot as plt
fs = 1000 # サンプリング周波数
cutoff = 200 # カットオフ周波数
coeffs = make_low_pass_coeffs(cutoff, fs)
fir_filter = Fir(coeffs)
# テスト信号の生成
t = np.linspace(0, 1, fs, endpoint=False)
t = t[0:fs//5]
input_signal = np.sin(2 * np.pi * 50 * t) + np.sin(2 * np.pi * 300 * t) # 50Hzと300Hzの混合信号
# フィルタ処理
output_signal = fir_filter.process(input_signal)
plt.plot(t, input_signal)
plt.plot(t, output_signal)
plt.show()
結果

最初、信号がないのはFIRフィルタの遅延によるものです。青色が入力波形、オレンジ色が出力波形になります。確認すると、高周波成分が除去され、単一の正弦波のみになっていることが確認できます。
まとめ
本記事では、Pythonでローパスフィルタを作成しました。
コメント