前提・実現したいこと
wavファイルを読み込み、FFTさせて低周波にでたピークをハイパスフィルタで処理をしてまた時間信号に戻してどんな変化があったかを見たのですが、そこにローパスフィルタ処理を増やして高周波に出ている雑音をなくしたいと思っています。
該当のソースコード
import sys import scipy.io.wavfile from scipy.fftpack import rfft,irfft,fftfreq import numpy as np import matplotlib.pyplot as plt #音声ファイル読み込み args = sys.argv wav_filename = args[1] rate, data = scipy.io.wavfile.read(wav_filename) #縦軸(振幅)の配列を作成 data = data / 32768 #横軸(時間)の配列を作成 #np.arange(初項, 等差数列の終点, 等差) time = np.arange(0, data.shape[0]/rate, 1/rate) #縦軸:dataを高速フーリエ変換する(時間領域から周波数領域に変換する) fft_data = np.fft.fft(data) #横軸:周波数の取得 #np.fft.fftfreq(データ点数, サンプリング周期) freqList = np.fft.fftfreq(data.shape[0], d=1.0/rate) # 正規化 + 交流成分2倍 fft_data = fft_data/24000 #サンプル数/2 #fft_data[0] = fft_data[0]/2 # 配列fft_dataをコピー fft_data2 = fft_data.copy() # highpass処理 fft_data2[(freqList < 60)&(freqList > -60)] = 0 #fc = 60 # 高速逆フーリエ変換(時間信号に戻す) data2 = np.fft.ifft(fft_data2) # 振幅を元のスケールに戻す data2 = np.real(data2*48000) #N = 16000*3 # グラフ表示 fig = plt.figure(figsize=(10.0, 8.0)) plt.rcParams['font.family'] = 'Times New Roman' plt.rcParams['font.size'] = 12 #データプロット #時間信号(before) plt.subplot(221) plt.plot(time,data,label = 'f(n)') plt.ylim(-1.5,1.5) plt.xlabel("Time", fontsize=12) plt.ylabel("Signal", fontsize=12) plt.grid() leg = plt.legend(loc=1, fontsize=15) leg.get_frame().set_alpha(1) #周波数信号(before) plt.subplot(222) plt.plot(freqList, np.abs(fft_data),label = 'F(k)') plt.xlim(-1000, 1000) plt.ylim(0,0.1) plt.xlabel('Frequency', fontsize=12) plt.ylabel('Amplitude', fontsize=12) plt.grid() leg = plt.legend(loc=1, fontsize=15) leg.get_frame().set_alpha(1) #時間信号(after) plt.subplot(223) plt.plot(time,data2,label = 'f2(n)') plt.ylim(-1.5,1.5) plt.xlabel("Time", fontsize=12) plt.ylabel("Signal", fontsize=12) plt.grid() leg = plt.legend(loc=1, fontsize=15) leg.get_frame().set_alpha(1) #周波数成分(after) plt.subplot(224) plt.plot(freqList,np.abs(fft_data2),label = 'F2(k)') plt.xlim(-1000,1000) plt.ylim(0,0.1) plt.xlabel('Frequency', fontsize=12) plt.ylabel('Amplitude', fontsize=12) plt.grid() leg = plt.legend(loc=1, fontsize=15) leg.get_frame().set_alpha(1) plt.show()
コマンド実行例: python ~.py ~.wav
試したこと
ハイパス処理を行っている
fft_data2[(freqList < 60)&(freqList > -60)] = 0
の部分で、
fft_data2[(freqList < 60)&(freqList > -60)|(freqList > 1000)&(freqList) < -1000)] = 0
を試してみたが駄目だった。
補足情報(FW/ツールのバージョンなど)
anaconda3を使用
> fft_data2[(freqList < 60)&(freqList > -60)&(freqList > 1000)&(freqList) < -1000)] = 0
・60より小さく、かつ、1000より大きい
・-60より大きく、かつ、-1000より小さい
は、有り得ませんよね
「かつ(&)」と「または(|)」を使い分けてください
修正の依頼ありがとうございます。
気づきませんでした。修正いたします。
> fft_data2[(freqList < 60)&(freqList > -60)|(freqList > 1000)&(freqList) < -1000)] = 0
で実行してみましたがプロットされた画像は変わりませんでした。
1000より大きく、かつ、-1000より小さい
も有り得ない
たしかに...
どのようにあらわせばよいのでしょうか。
バンドパスフィルタ処理をするというよりは、-60<freqList<60&freqList<-1000,1000<freqListの範囲で0にしたいです。
(freqList > 1000)&(freqList) < -1000)
のところを
(freqList > 1000)|(freqList) < -1000)
と変えて、グラフで確認してください
グラフの横軸周波数の範囲を広げて
-1000〜1000だと、カットされてるか分からないので
> バンドパスフィルタ処理をするというよりは
あれ、バンドパスじゃないんですか?
ハイパス=ローカット
と
ローパス=ハイカット
を同時にやったら、
ローカットandハイカット=バンドパス
になりますけど
> -60<freqList<60&freqList<-1000,1000<freqListの範囲で0にしたい
説明を簡単にするために、周波数は整数しかないとして書きます
-60<freqList<60:-59,-58,-57...57,58,59を0にする
freqList<-1000:マイナス側の端(ナイキスト周波数)...-1003,-1002,-1001を0にする
1000<freqList:1001,1002,1003...プラス側の端(ナイキスト周波数)を0にする
上記を全て行うと、その結果下記の周波数だけ残る
-1000,-999,-998...-62,-61,-60 と 60,61,62...998,999,1000
これはバンドパスフィルタです
やりたいことは、上記とは違うのですか?
すません
なんか言い方がおかしかったです
そういうことです
fft_data2[(freqList < 60)&(freqList > -60)] = 0
fft_data2[(freqList > 1000)|(freqList < -1000)] = 0
とすることで改善されました
回答1件
あなたの回答
tips
プレビュー