人工知能に関する断創録

人工知能、認知科学、心理学、ロボティクス、生物学、ゲームAIなどに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。最近は、音声認識・音声合成、複雑系(カオス、力学系)、Deep Learning、Unityなど。



バンドストップフィルタ

Pythonで音声信号処理(2011/05/14)

バンドパスフィルタ(2011/10/30)の続き。今回は、バンドストップフィルタ(バンドリミットフィルタ、バンドエリミネーションフィルタという呼び方もあるとのこと)を実験します。バンドストップフィルタは、バンドパスフィルタの反対です。バンドストップフィルタは、エッジ周波数を2つ指定し、ある周波数からある周波数までの領域を通さないようなフィルタです。式で書くと

f:id:aidiary:20111029224537p:plain

となります。これを逆フーリエ変換してフィルタ係数b(i)を求めると、

f:id:aidiary:20111029224720p:plain

となります。LPF、HPF、BPFと同様にb(i)は無限個のフィルタ係数を持つため窓関数をかけて有限で打ち切ります。

LPF、HPF、BPFのプログラムとほとんど同じなので差分のみ書きます。これだけでは動きません。コード全体は、ローパスフィルタ(2011/10/28)を参照のこと。

def createBSF(fe1, fe2, delta):
    """バンドストップフィルタを設計、fe1:エッジ周波数(低)、fe2:エッジ周波数(高)
    delta:遷移帯域幅"""
    # 遷移帯域幅を満たすフィルタ係数の数を計算
    # N+1が奇数になるように調整が必要
    N = round(3.1 / delta) - 1
    if N + 1 % 2 == 0: N += 1
    N = int(N)


    # フィルタ係数を求める
    b = []
    for i in range(-N/2, N/2 + 1):
        b.append(sinc(math.pi * i) - 2 * fe2 * sinc(2 * math.pi * fe2 * i) + 2 * fe1 * sinc(2 * math.pi * fe1 * i))

    # ハニング窓をかける(窓関数法)
    hanningWindow = np.hanning(N + 1)
    for i in range(len(b)):
        b[i] *= hanningWindow[i]

    return b

fe1 = 1000.0 / fs
fe2 = 3000.0 / fs
b = createBSF(fe1, fe2, delta)
# フィルタをかける
y = fir(x, b)

結果は、

f:id:aidiary:20111029220424p:plain

となります。上がb(i)で下がB(f)です。B(f)を見るとエッジ周波数fe1の1000Hzからfe2の3000Hzまでの領域は0を掛けるので0に減衰し、それ以外の領域は1を掛けるためそのまま通ります。ためしに、ホワイトノイズに上のBSFを適用してみました。結果は、

f:id:aidiary:20111029220441p:plain

となります。これで、FIRフィルタの代表例であるローパスフィルタ、ハイパスフィルタ、バンドパスフィルタ、バンドストップフィルタが実装できました。で、ここまできてはっと気づきました。scipyにこれらの超重要フィルタを求める関数がないはずないではないか!案の定あったので次はscipyの関数を使ってみたいと思います。

まあ、一度くらい自分で実装してみるのも悪くないかな。理解が深まりました。