Python'da spektrogram çözünürlüğünün iyileştirilmesi?


21

Python'da konuşma dalgası dosyalarının spektrogramlarını oluşturma specgram()işlevini kullanıyorum matplotlib, ancak çıktı her zaman normal transkripsiyon yazılımım Praat'ın üretebildiklerinden çok daha düşük kalitede. Örneğin, aşağıdaki arama:

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

Bunu oluşturur:

görüntü tanımını buraya girin

Praat kullanırken, aynı ses örneğinde aşağıdaki ayarlarla çalışma:

  • Görüş aralığı: 0-8000Hz
  • Pencere uzunluğu: 0,005
  • Dinamik aralık: 70dB
  • Zaman adımları: 1000
  • Frekans adımları: 250
  • Pencere şekli: Gaussian

Bunu oluşturur:

görüntü tanımını buraya girin

Neyi yanlış yapıyorum? Tüm specgram()parametrelerle uğraşmayı denedim , ancak hiçbir şey çözünürlüğü iyileştirecek gibi görünmüyor. FFT'ler ile ilgili neredeyse hiçbir deneyimim yok.


Denediğiniz matplotlib.specgram parametre yapılandırmalarına bir örnek verebilir misiniz? Praat için parametrelere çok özel bir örnek veriyorsunuz, ancak matplotlib.specgram için aynı yapılandırmayı göstermiyor musunuz?
Christopher Felton,

Yanıtlar:


11

İşte matplotlib.specgram parametreleri

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)

Soru açıklamasında sağlanan parametrelerin karşılaştırılabilir mpl.specgram parametrelerine dönüştürülmesi gerekir. Aşağıdaki eşleme örneğidir:

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 kullanırsanız 2 FFT (128) gücüne sahip olursunuz. Aşağıdaki Praat ayarlarının web sitesinden açıklamasıdır.

Görüntüleme aralığı (Hz) : Gösterilecek frekans aralığı. Standart altta 0 Hz ve üstte 5000 Hz'dir. Bu maksimum frekans, Sesin Nyquist frekansından (örnekleme frekansının yarısı kadar) daha yüksekse, spektrogramdaki bazı değerler sıfır olur ve yüksek frekanslar beyaz olarak çizilir. 44100 Hz'de bir Ses kaydederseniz ve görüş aralığını 0 Hz ile 25000 Hz arasında ayarladıysanız bunu görebilirsiniz.

Pencere uzunluğu : Analiz penceresinin süresi. Bu 0,005 saniye ise (standart), Praat her kare için, sesin bu karenin ortasından 0,0025 saniye ile 0,0025 saniye arasında kalan kısmını kullanır (Gauss pencereleri için Praat aslında bundan biraz daha fazla kullanır). Pencere uzunluğu, spektral analizin bant genişliğini, yani saf sinüs dalgasının spektrogramındaki yatay çizginin genişliğini belirler (aşağıya bakınız). Gaussian bir pencere için -3 dB bant genişliği 2 * sqrt (6 * ln (2)) / (π * Pencere uzunluğu) veya 1.2982804 / Pencere uzunluğu'dur. Bir elde etmek için broad-band' spectrogram (bandwidth 260 Hz), keep the standard window length of 5 ms; to get adar bantlı' spektrogram (bant genişliği 43 Hz), 30 ms (0.03 saniye) olarak ayarlanır. Diğer pencere şekilleri biraz farklı değerler verir.

Dinamik aralık (dB) : Maksimum değerin altındaki Dinamik aralık dB'den daha büyük olan tüm değerler (belki dinamik sıkıştırmadan sonra, bkz. Gelişmiş spektrogram ayarları ...) beyaz olarak çizilecektir. Aradaki değerler uygun gri tonlarına sahiptir. Bu nedenle, spektrogramdaki en yüksek tepe 30 dB / Hz yüksekliğe sahipse ve dinamik aralık 50 dB (standart değer olan) ise, -20 dB / Hz'nin altındaki değerler beyaz renkte çizilir ve arasındaki değerler -20 dB / Hz ve 30 dB / Hz, çeşitli gri tonlarında çizilecektir.

Praat ayarlarına bağlantı

OP'nin sorusu Praat specgram ve mpl (matplotlib) specgram arasındaki kontrast farkıyla ilgili olabilir. Praat, kontrastı etkileyen bir Dinamik Aralık ayarına sahiptir. Mpl işlevi benzer bir ayara / parametreye sahip değildir. Mpl.specgram, dinamik dizinin dönüş dizisine uygulanıp yeniden çizilebileceği 2B dizi güç düzeyini (spektrogram) döndürür.

Aşağıdaki grafikler oluşturmak için bir kod pasajıdır. Örnek, 20Hz-8000Hz'den bir cıvıltı ile ~ 1m15s'lik bir konuşmadır.

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
Bunu biraz daha fazla düşünerek, Praat "Dinamik Aralık" parametresi, arazilerin görünüş şeklindeki farkın ana faktörü olabilir. Praat "Dinamik Menzil", menzili sınırlıyor olabilir (kompresyon), böylece çizimde daha büyük bir kontrast elde edersiniz. BOMK MPL benzer bir özelliğe sahip değil ama bir tane daha eklenebilir.
Christopher Felton

6

Zaman / frekans çözünürlüğü problemi gibi görünüyor. Praat planınız daha kötü bir frekans çözünürlüğüne (harmonikleri bile net bir şekilde göremezsiniz) ve daha iyi bir zaman çözünürlüğüne sahiptir. Pencere boyutunu (NFFT) 16000 x 0.05 = 80 örneklere düşürmeyi deneyin. Pad_to'da (128 veya 256) 2 daha büyük bir güç kullanmanızı öneririm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.