質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
フィルタ

フィルタとは、特定の条件に合わせてデータへのアクセスをブロックするプログラムやルーチンを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2721閲覧

scipy.signal.decimate()を使っても時間信号の波形に変化が見られません。

iface

総合スコア42

フィルタ

フィルタとは、特定の条件に合わせてデータへのアクセスをブロックするプログラムやルーチンを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/07 12:37

前提・実現したいこと

wavファイルを読み込み、scipy.signal.decimate()を用いてLPF込みの間引きを行いダウンサンプリング前後でグラフを比較してみました。
今回この関数を使った理由は、機械学習でフィルタ処理の効果について調べてまして、LPFのカットオフ周波数を考えたりせずフィルタ処理を行えると思ったからです。

発生している問題

時間信号での間引き前後の比較を行うと、見た目は全く変わらず、
周波数信号での間引き前後の比較を行うと、低周波数域が大幅に削減された状態になった。

terateilの都合上、プロット画像をお見せすることができませんが、低周波数域が大幅にカットされても、時間信号でグラフにあまり変化が見られないものでしょうか。

該当のソースコード

python

1import numpy as np 2import matplotlib.pyplot as plt 3import sys 4import scipy.io.wavfile 5from scipy.io.wavfile import write 6from scipy.io.wavfile import read 7from scipy.fftpack import rfft,irfft,fftfreq 8from scipy import signal 9 10##音声ファイル読み込み## 11args = sys.argv 12wav_filename = args[1] 13rate, data = scipy.io.wavfile.read(wav_filename) 14time = np.arange(0,data.shape[0]/rate,1/rate) #時間軸作成 15 16print(len(time)) 17print(len(data)) 18print("data_MAX:",np.max(data)) 19print("data_min:",np.min(data)) 20 21 22#dataを高速フーリエ変換 23fft_data = np.fft.fft(data) 24freqList = np.fft.fftfreq(data.shape[0], 1.0/rate) #周波数取得 25 26fft_data = fft_data/22050 #サンプル数/2 27 28 29###################### scipy.signal.decimate ############################# 30data_d = signal.decimate(data, 10) # 間引き 31rate_d = rate/10 #間引き後のサンプリング周波数 32time_d = np.arange(0,data_d.shape[0]/rate_d,1/rate_d) #間引き後の時間軸 33 34print("data_d:",len(data_d)) 35print("time_d:",len(time_d)) 36print("data_d_MAX:",np.max(data_d)) 37print("data_d_min:",np.min(data_d)) 38 39#dataを高速フーリエ変換 40fft_data_d = np.fft.fft(data_d) 41freqList_d = np.fft.fftfreq(data_d.shape[0], 1.0/rate_d) #周波数取得 42 43fft_data_d = fft_data_d/22050 #サンプル数/2 44 45###################################################################################### 46 47 48 49######################## グラフ表示 ########################################## 50fig = plt.figure(figsize=(10.0, 4.0)) 51plt.rcParams['font.family'] = 'Times New Roman' 52plt.rcParams['font.size'] = 12 53 54#データプロット 55#時間信号(before) 56plt.subplot(211) 57plt.plot(time,data,color='g') # 単純間引きの時間波形 58plt.plot(time_d,data_d,'darkorange') # decimate()による間引きの時間波形 59plt.xlim(0,5) 60plt.xlabel("Time", fontsize=12) 61plt.ylabel("Signal", fontsize=12) 62plt.grid() 63plt.legend(['before decimation','filtered decimation'], loc=1) 64 65#周波数信号(before) 66plt.subplot(212) 67plt.plot(freqList, np.abs(fft_data),color='g') 68plt.plot(freqList_d, np.abs(fft_data_d),color='darkorange') 69plt.xlim(0, 5000) 70plt.xlabel('Frequency', fontsize=12) 71plt.ylabel('Amplitude', fontsize=12) 72plt.grid() 73leg = plt.legend(loc=1, fontsize=15) 74plt.legend(['before decimation','filtered decimation'], loc=1) 75 76plt.show() 77plt.close()

試したこと

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/11/07 13:02 編集

> 時間信号での間引き前後の比較を行うと、見た目は全く変わらず グラフの横軸の範囲を、間引き前の元データが30〜50個くらいしか表示されないくらいの範囲に設定して、間引き前/後のデータをグラフに重ね書きして比べてみたら、データの一個一個が見えるので間引きの効果が分かると思います
jbpb0

2021/11/08 01:50

> 周波数信号での間引き前後の比較を行うと、低周波数域が大幅に削減された状態になった。 間引きでデータ数が減ってるのに、 > fft_data = fft_data/22050 #サンプル数/2 と > fft_data_d = fft_data_d/22050 #サンプル数/2 の割り算の分母が同じだからです データを1/10に間引いた場合は、後者の割り算の分母は前者の約1/10になりますけど、そうしてないので間引いたデータの振幅が割り算後に1/10になってしまいます コード中に数値を書くと、上記のような間違いをしやすくなるし、元の音声データを変えた時とか、どれくらい間引きするかを変えた時とかに、数値を書き換えるのを忘れて間違うことも起きやすくなるので、数値を書かずに「data.shape[0]」と「data_d.shape[0]」を使うようにコードを変える方がいいですよ
iface

2021/11/08 03:27

回答ありがとうございます。 上記の方法で時間信号を確認したところしっかり間引きされていることを確認することができました。
iface

2021/11/08 03:36 編集

コードを数値で書くと間違えやすくなってしまうことがわかりました。 > fft_data = fft_data/22050 #サンプル数/2  →fft_data = fft_data / rate / 2 > fft_data_d = fft_data_d/22050 #サンプル数/2  →fft_data_d = fft_data_d / rate_d / 2 と変換しました。 周波数信号もbeforeとほぼ同じ形になりました。
iface

2021/11/08 03:43

jbpb0様 いつもありがとうございます。 ベストアンサーにさせていただきたいので回答の方にお願い致します。
iface

2021/11/08 16:22

こちらの方法で間引き前とほぼ同じ振幅を得ることができました。ありがとうございました。
guest

回答1

0

ベストアンサー

時間信号での間引き前後の比較を行うと、見た目は全く変わらず

グラフの横軸の範囲を、間引き前の元データが30〜50個くらいしか表示されないくらいの範囲に設定して、間引き前/後のデータをグラフに重ね書きして比べてみたら、データの一個一個が見えるので間引きの効果が分かると思います

 .

周波数信号での間引き前後の比較を行うと、低周波数域が大幅に削減された状態になった。

間引きでデータ数が減ってるのに、

fft_data = fft_data/22050 #サンプル数/2

fft_data_d = fft_data_d/22050 #サンプル数/2

の割り算の分母が同じだからです

データを1/10に間引いた場合は、後者の割り算の分母は前者の約1/10になりますけど、そうしてないので間引いたデータの振幅が割り算後に1/10になってしまいます

投稿2021/11/08 07:56

jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問