как получить правильную спектрограмму нестационарного сигнала?

в приведенном ниже коде я пытаюсь получить spectrogram нестационарного сигналаx после запуска кода, я ожидал увидеть что-то вроде опубликованного изображения "image_2", частоты и времени. но результатом опубликованного кода является image_1.

может ли кто-нибудь помочь мне получить правильный spectrogram?

Код

% Time specifications:
Fs = 8000;                       % samples per second
 dt = 1/Fs;                       % seconds per sample
  StopTime = 1;                    % seconds
  t = (0:dt:StopTime-dt);             % seconds
 t1 = (0:dt:.25);
 t2 = (.25:dt:.50);
 t3 = (.5:dt:.75);
 t4 = (.75:dt:1);

 %get a full-length example of each signal component
 x1 = (10)*sin(2*pi*100*t);
 x2 = (10)*sin(2*pi*200*t);
 x3 = (10)*sin(2*pi*300*t);
 x4 = (10)*sin(2*pi*400*t);

  %construct a composite signal
  x = zeros(size(t));
  I = find((t >= t1(1)) & (t <= t1(end)));
  x(I) = x1(I);
  I = find((t >= t2(1)) & (t <= t2(end)));
  x(I) = x2(I);
  I = find((t >= t3(1)) & (t <= t3(end)));
  x(I) = x3(I);
  I = find((t >= t4(1)) & (t <= t4(end)));
  x(I) = x4(I);

  NFFT = 2 ^ nextpow2(length(t));     % Next power of 2 from length of y
   Y    = fft(x, NFFT);
   f    = Fs / 2 * linspace(0, 1, NFFT/2 + 1);
   figure;
   plot(f(1:200), 2 * abs( Y( 1:200) ) );

   T = 0:.001:1;
   spectrogram(x,10,9);
   ylabel('Frequency');
    axis(get(gcf,'children'), [0, 1, 1, 100]);

результат опубликованного кода: Spectrogram_Image_1: введите здесь описание изображения

что я пытаюсь получить: Image_2: введите здесь описание изображения

Обновление_1, изображение Код:

%now call the spectrogram
spectrogram(x, window, noverlap, Nfft, Fs);
ylabel('Frequency');
axis(get(gcf,'children'), [0, 1]);

введите здесь описание изображения


person rmaik    schedule 03.01.2015    source источник


Ответы (1)


Во-первых, как и в первый раз, когда вы задали этот вопрос, построили ли вы данные во временной области (т. е. plot(t, x)) и увеличили ли переходы, чтобы убедиться, что ваш сигнал именно такой, как вы думаете? Есть ли у него четыре разных периода с разными частотами, как вы предполагали?

Предполагая, что это так, я почти уверен, что ваша проблема в том, что ваш вызов spectrogram не делает то, что вы хотите. Я думаю, что вы получаете только NFFT, равный 10, что означает, что ваши ячейки имеют ширину 800 Гц, что недостаточно для разрешения частот, отстоящих друг от друга всего на 100 Гц.

На мой взгляд, вам следует указать больше параметров, чтобы вы знали, что он делает. Вы бы указали Nfft, который даст нужное разрешение по частоте. Что-то с более высоким разрешением, чем 100 Гц (попробуем 25 Гц), но не требующее такого количества точек, чтобы оно превышало продолжительность, при которой у вас есть стабильные частоты (то есть менее 0,25 с, что означает менее 2000 точек).

Чтобы узнать, как указать длину БПФ, я просмотрел документацию: http://www.mathworks.com/help/signal/ref/spectrogram.html

Основываясь на документах, я бы попробовал версию с пятью параметрами: spectrogram(x,window,noverlap,nfft,fs)

Для вашего кода, где Fs и x уже определены, вызов спектрограммы будет выглядеть так:

%define FFT parameters
des_df_Hz = 25;  %desired frequency resolution for the display, Hz
Nfft = round(FS / des_df_Hz);  %general rule for FFT resolution
Nfft = 2*Nfft;  %double the bins to account for spreading due to windowing
Nfft = 2*round(0.5*Nfft);  %make Nfft an even number
window = Nfft;  %make your window the same length as your FFT
noverlap = round(0.95);  %overlap a lot to make the plot pretty

%now call the spectrogram
spectrogram(x, window, noverlap, Nfft, Fs,'yaxis');
person chipaudette    schedule 03.01.2015
comment
чем вам за ответ, вроде правильно, но оси надо настроить. подскажите пожалуйста как правильно настроить оси? Я хочу, чтобы горизонтальные оси отображали время, а вертикальные оси — частоту, бит с соответствующими выводами выборки. см. раздел update_1, размещенный выше - person rmaik; 04.01.2015
comment
В документации по спектрограмме Matlab (mathworks.com/help/signal/ref/spectrogram. html), его пример показывает частоту по вертикальной оси по вашему желанию. В нем сказано добавить аргумент 'yaxis' к вызову функции. Я отредактировал свой код выше. Я также увеличил перекрытие, чтобы спектрограмма выглядела более гладкой. - person chipaudette; 04.01.2015
comment
Кроме того, вы захотите удалить свою команду axis, которая будет обрезать ось Y (которая вскоре станет осью частот) так, чтобы она колебалась только от нуля до герц. Это тоже сейчас. Как только вы внесете изменения в вызов spectrogram, вы захотите заменить свою команду axis чем-то более простым, например ylim([0 1000]);. - person chipaudette; 04.01.2015
comment
спасибо, я сообщу правильность ответа, как только попробую +1 - person rmaik; 07.01.2015