Pythonでスペクトログラムの解像度を改善しますか?


21

specgram()関数を使用matplotlibしてPythonで音声波形ファイルのスペクトログラムを生成していますが、出力は常に、通常の文字起こしソフトウェアPraatが生成できる品質よりも非常に劣っています。たとえば、次の呼び出し:

specgram(
    fromstring(spf.readframes(-1), 'Int16'),
    Fs=framerate,
    cmap=cm.gray_r,
)

これを生成します:

ここに画像の説明を入力してください

Praatが次の設定で同じオーディオサンプルに取り組んでいる間:

  • 表示範囲:0-8000Hz
  • ウィンドウの長さ:0.005s
  • ダイナミックレンジ:70dB
  • 時間ステップ:1000
  • 周波数ステップ:250
  • ウィンドウ形状:ガウス

これを生成します:

ここに画像の説明を入力してください

私は何を間違えていますか?すべてのspecgram()パラメーターをいじってみましたが、解像度を改善できるものはありません。FFTの経験はほとんどありません。


試したmatplotlib.specgramパラメーター構成の例を教えてください。Praatのパラメーターの非常に具体的な例を挙げますが、matplotlib.specgramの同じ構成を表示しませんか?
クリストファーフェルトン

回答:


11

matplotlib.specgramのパラメーターは次のとおりです。

matplotlib.mlab.specgram(x, 
                         NFFT=256, 
                         Fs=2, 
                         detrend=<function detrend_none at 0x1dd6410>, 
                         window=<function window_hanning at 0x1e0b1b8>, 
                         noverlap=128, 
                         pad_to=None, 
                         sides='default', 
                         scale_by_freq=None)

質問の説明で提供されるパラメーターは、同等のmpl.specgramパラメーターに変換する必要があります。以下は、マッピングの例です。

View range: 0-8000Hz            Fs=16000
Window length: 0.005s           NFFT = int(Fs*0.005) = 80
                                noverlap = int(Fs*0.0025) = 40
Dynamic range: 70dB             n/a
Time steps: 1000                n/a
Frequency steps: 250            
Window shape: Gaussian          default window is hanning change to gaussian

8msを使用すると、2のべき乗(128)が得られます。以下は、ウェブサイトのPraat設定の説明です

表示範囲(Hz):表示する周波数の範囲。標準は、下部が0 Hz、上部が5000 Hzです。この最大周波数がサウンドのナイキスト周波数(サンプリング周波数の半分)よりも高い場合、スペクトログラムの一部の値はゼロになり、より高い周波数は白で描画されます。44100 Hzでサウンドを録音し、0 Hzから25000 Hzの表示範囲を設定すると、これを確認できます。

ウィンドウの長さ:分析ウィンドウの期間。これが0.005秒(標準)の場合、Praatは各フレームに対して、そのフレームの中心の0.0025秒前から0.0025秒の間にある音の部分を使用します(ガウスウィンドウの場合、Praatは実際にそれよりも少し多く使用します)。ウィンドウの長さは、スペクトル解析の帯域幅、つまり純粋な正弦波のスペクトログラムの水平線の幅を決定します(以下を参照)。ガウスウィンドウの場合、-3 dB帯域幅は2 * sqrt(6 * ln(2))/(π* Window length)、または1.2982804 / Window lengthです。broad-band' spectrogram (bandwidth 260 Hz), keep the standard window length of 5 ms; to get a狭帯域のスペクトログラム(帯域幅43 Hz)を取得するには、30 ms(0.03秒)に設定します。他のウィンドウ形状は、わずかに異なる値を与えます。

ダイナミックレンジ(dB):ダイナミックレンジdBが最大値を下回るすべての値(おそらく、ダイナミック圧縮の後、スペクトログラムの詳細設定を参照)は白で描画されます。中間の値には適切なグレーの濃淡があります。したがって、スペクトログラムの最高ピークの高さが30 dB / Hzで、ダイナミックレンジが50 dB(これが標準値)の場合、-20 dB / Hz未満の値は白で描画され、その間の値は-20 dB / Hzおよび30 dB / Hzは、さまざまなグレーの陰影で描画されます。

プラートの設定へのリンク

OPの質問は、Praatスペックグラムとmpl(matplotlib)スペックグラムのコントラストの違いに関するものかもしれません。Praatには、コントラストに影響するダイナミックレンジ設定があります。mpl関数には、同様の設定/パラメーターはありません。mpl.specgramは、出力レベルの2D配列(スペクトログラム)を返しますが、ダイナミックレンジは戻り配列に適用され、再プロットされます。

以下は、以下のプロットを作成するためのコードスニペットです。例は、20Hzから8000Hzのチャープを持つ1m15sまでの音声です。

import numpy
import pylab
import wave
import array
pylab.close('all')
w1 = wave.open('example_no_noise.wav')
w2 = wave.open('example_noise.wav')
# hmmm, probably a better way to do this, scipy.io function?
x1 = numpy.array(array.array('h', w1.readframes(w1.getnframes())))
x2 = numpy.array(array.array('h', w2.readframes(w2.getnframes())))
x1 = x1 / (2.**(16-1))  # normalize
x2 = x2 / (2.**(16-1))  # normalize
Fs = 16000.
NFFT = int(Fs*0.005)  # 5ms window
noverlap = int(Fs*0.0025)
pylab.figure(1)
pylab.specgram(x1, NFFT=NFFT, Fs=Fs, noverlap=noverlap, 
               cmap=pylab.get_cmap('Greys'))
pylab.title('Full 1m15s example min noise')
pylab.figure(2)
pylab.specgram(x2, NFFT=NFFT, Fs=Fs, noverlap=noverlap, 
               cmap=pylab.get_cmap('Greys'))
pylab.title('Full 1m15s example more noise')
pylab.figure(3); n=2100*176;
pylab.specgram(x2[n:n+256*256], NFFT=NFFT, Fs=Fs, noverlap=noverlap, 
               cmap=pylab.get_cmap('Greys'))
pylab.title('Full ~4s example min noise')
pylab.figure(4); pylab.plot(x1[n:n+256*256])


1
これについてもう少し考えてみると、Praatの「ダイナミックレンジ」パラメータが、プロットの外観の違いの主な要因である可能性があります。Praatの「ダイナミックレンジ」は、プロットのコントラストを大きくするために、範囲を制限する(圧縮する)場合があります。BOMK MPLには同様の機能はありませんが、追加できます。
クリストファーフェルトン

6

時間/周波数の解像度の問題のようです。Praatプロットの周波数分解能は低下しており(高調波をはっきりと見ることさえできません)、時間分解能は向上しています。ウィンドウサイズ(NFFT)を16000 x 0.05 = 80サンプルに減らしてみてください。pad_toで2の累乗(128または256)を使用することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.