2016-06-19 16 views
0

Ich verwende matplotlib.specgram, um Spektrogramme von Aufzeichnungen von gesprochenen Wörtern zu erstellen. Aus einem mir unbekannten Grund haben die Spektrogramme seltsame Linien, wie aus den Bildern unten ersichtlich.Seltsame Linien im Specgramm mit Matplotlib

Ich frage mich, was diese Linien verursacht und wie kann ich sie loswerden?

Example spectrogram Example spectrogram

+0

Es ist schwer zu sagen, ohne die Code + Daten, die verwendet, um dies zu generieren, aber es sieht für mich aus wie die "Linien" sind tatsächlich eine Art zugrunde liegenden diskrete und dramatische Änderung in Ihrem Dataset. – farenorth

Antwort

0

Ich denke, dass @farenorth richtig ist.

Wenn das Spektrogramm berechnet wird, wird für jeden Zeitschritt (x-Achse) eine bestimmte Graustufe für eine bestimmte Intensität ausgewählt. Angenommen, die Graustufen sind global festgelegt. Wenn Sie in einem neuen Zeitschritt plötzlich höhere Intensitäten haben, werden die Graustufen gesättigt.

Dies wäre ein echtes Problem, wenn Sie in Echtzeit arbeiten würden, da Sie mit sehr leiser Audio beginnen könnten, die plötzlich laut wird, aber Sie müssen zu Beginn ein Graustufen-/Intensitätsverhältnis wählen auf Kenntnis vergangener Audiotracks.

Der Ansatz von 'mlab.specgram' ist also, alle Zeitschritte unabhängig zu skalieren. Wenn sich also während eines Zeitschritts eine plötzliche Änderung ergibt, sehen die Dinge nicht vergleichbar mit den benachbarten Schritten aus, worauf @farenorth hinwies.

Ein synthetisches Beispiel unten. Der obere Plot ist nur eine gechirpte Sinuswelle, die unteren Plots sind die gleichen mit einem plötzlichen Knall.

'''specgram(x, NFFT=256, Fs=2,detrend=mlab.detrend_none, 
     window=mlab.window_hanning, noverlap=128, 
     cmap=None, xextent=None, pad_to=None, sides='default', 
     scale_by_freq=None, mode='default')''' 

import numpy as np 
import matplotlib.pyplot as p 

%matplotlib inline 

time= np.arange(1,5,0.0004) 
time=np.linspace(1,5,1024*16) 
f= 50+ time*50 
#add a bang 
bang=np.ones(len(time)) 
bang[ len(time)/2:len(time)*3/4]=100 


chirp1= np.sin(2*np.pi*f*time) 
chirp2= np.sin(2*np.pi*f*time) *bang 

p.figure(figsize=((20,8))) 
p.subplot(221) 
p.plot(chirp1) 
p.subplot(222) 
p.specgram(chirp1 ,noverlap=0,cmap=p.cm.gray) 

p.subplot(223) 
p.plot(chirp2) 
p.subplot(224) 
p.specgram(chirp2 ,noverlap=0,cmap=p.cm.gray) 
p.show() 

enter image description here

Sie nicht mit davon befreien specgram, erhalten können, da keine Option für die globale Skalierung ist. Aber Sie könnten leicht Ihre eigene STFT oder besser, ein Gabor-Spektrogramm (STFT mit Gauß-Fenster, wenn ich es richtig verstehe) rollen.

Verwandte Themen