Неправильная спектрограмма при использовании scipy.signal.spectrogram - PullRequest
0 голосов
/ 26 июня 2018

Когда я использую plt.specgram из matplotlib, используя следующий код, генерируемая спектрограмма является правильной

import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
import numpy as np

sample_rate, samples = wavfile.read('.\\Wav\\test.wav')

Pxx, freqs, bins, im = plt.specgram(samples[:,1], NFFT=1024, Fs=44100, noverlap=900)

spectrogram generated by using matplotlib

Однако, если я сгенерирую спектрограмму, используя пример кода, указанный на странице scipy со следующим кодом, я получу что-то вроде этого:

import matplotlib.pyplot as plt
from scipy import signal
from scipy.io import wavfile
import numpy as np

sample_rate, samples = wavfile.read('.\\Wav\\test.wav')

frequencies, times, spectrogram = signal.spectrogram(samples[:,1],sample_rate,nfft=1024,noverlap=900, nperseg=1024)

plt.pcolormesh(times, frequencies, spectrogram)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

enter image description here

Чтобы отладить происходящее, я попытался использовать Pxx, freqs, bins, сгенерированные первым методом, а затем использовать второй метод для вывода данных:

plt.pcolormesh(bins, freqs, Pxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')

enter image description here

Сгенерированный график почти такой же, как график, сгенерированный вторым методом. Так что, похоже, с scipy.signal.spectrogram проблем нет. Проблема в том, как мы строим график. Интересно, является ли plt.pcolormesh правильным способом построения спектрограммы, несмотря на тот факт, что этот метод предлагается в scipy документе

Подобный вопрос был задан здесь , но пока нет решения вопроса.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Используйте это вместо:

plt.pcolormesh(times, frequencies, spectrogram, norm = matplotlib.colors.Normalize(0,1))

Это нормализует данные перед построением графика, чтобы вы могли правильно визуализировать цвет. В документации matplotlib.colors.Colormap говорится: «Обычно экземпляры Colormap используются для преобразования значений данных (с плавающей запятой) из интервала [0, 1] в цвет RGBA, который представляет соответствующая Colormap». Если ваши значения находятся за пределами этого диапазона, он, вероятно, отобразит его в темном цвете (я полагаю.)

0 голосов
/ 26 июня 2018

Режим масштабирования по умолчанию для «Спектрама» - «дБ» (из документов по программе)

масштаб: [‘по умолчанию’ | «Линейный» | ‘ДБ’] Масштабирование значений в спец. «Линейный» - это не масштабирование. ‘дБ’ возвращает значения в шкале дБ. Когда режим «psd», это мощность дБ (10 * log10). В противном случае это амплитуда дБ (20 * log10). «По умолчанию» - «дБ», если режим «psd» или «величина» и «линейный» в противном случае. Это должен быть «линейный» режим, если «угол» или «фаза».

режим: [‘по умолчанию’ | ‘Psd’ | «Величина» | ‘Угол’ | ‘Фаза’] Какой спектр использовать. По умолчанию is psd ’, который принимает спектральную плотность мощности. «Complex» возвращает комплексный частотный спектр. «Величина» возвращает спектр величин. «Угол» возвращает фазовый спектр без развертывания. «Фаза» возвращает фазовый спектр с распаковкой.

Для достижения аналогичных результатов с pcolormesh вам необходимо эквивалентно масштабировать данные.

plt.pcolormesh(times, frequencies, 10*np.log10(spectrogram))

Я не думаю, что пример pcolormesh верен в своем масштабировании. Вы можете четко видеть несущую в примере, но добавленный шумовой сигнал не виден.

...