Построение распределения Вигнера-Вилля с помощью pytftb на python 3

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

pytftb предоставляет функцию wigner ville, которая хорошо работает с их примерами. Я использую это так:

tfr = WignerVilleDistribution(prepack[0])
tfr.run()
tfr.plot(show_tf=True)

И вроде работает:

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

Однако я не могу понять, что здесь происходит, поэтому я хотел бы изменить ось частоты и, возможно, напечатать относительно абсолютной частоты, а не нормализованной? Я действительно не понимаю Wigner Ville Distribution, поэтому, если я смотрю на это неправильно, я был бы признателен за помощь!


person Danf    schedule 05.04.2018    source источник
comment
Не могли бы вы опубликовать полный код, чтобы воспроизвести ваш пример, т. е. что вы импортируете, какой набор данных и т. д.   -  person Chachni    schedule 29.01.2021


Ответы (1)


Вот некоторый код для построения преобразования Вигнера-Вилля (WVT) с использованием абсолютной частоты. Я использую библиотеку Python: https://pypi.org/project/tftb/, версия 0.1. .1

Сначала я создаю сигнал:

import tftb
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as sig


T = 2  # signal duration
dt = 1/500  # sample interval/spacing
freq_s = 1/dt  # sampling frequency
N = T / dt  # number of samples
ts = np.arange(N) * dt  # times

#  constructing a chirp multiplied by a Gaussian
t0 = T/2
freq = np.linspace(10, 30, int(N))
sigma = 0.1
signal = np.cos((ts-t0) * 2 * np.pi * freq) * np.exp(-(ts-t0)**2/(2*sigma**2))/np.sqrt(sigma)

# adding some noise
signal += np.random.randn(len(signal))*0.5


#  plotting the signal
plt.figure()
plt.plot(ts, signal)
plt.show()

Вот график сигнала signal

Для справки я также построю спектрограмму перед WVT:

# first looking at the power of the short time fourier transform (SFTF):
nperseg = 2**6  # window size of the STFT
f_stft, t_stft, Zxx = sig.stft(signal, freq_s, nperseg=nperseg,
                           noverlap=nperseg-1, return_onesided=False)

# shifting the frequency axis for better representation
Zxx = np.fft.fftshift(Zxx, axes=0)
f_stft = np.fft.fftshift(f_stft)

# Doing the WVT
wvd = tftb.processing.WignerVilleDistribution(signal, timestamps=ts)
tfr_wvd, t_wvd, f_wvd = wvd.run()
# here t_wvd is the same as our ts, and f_wvd are the "normalized frequencies"
# so we will not use them and construct our own.

Теперь рисуем тепловые карты:

f, axx = plt.subplots(2, 1)

df1 = f_stft[1] - f_stft[0]  # the frequency step
im = axx[0].imshow(np.real(Zxx * np.conj(Zxx)), aspect='auto',
          interpolation=None, origin='lower',
          extent=(ts[0] - dt/2, ts[-1] + dt/2,
                  f_stft[0] - df1/2, f_stft[-1] + df1/2))
axx[0].set_ylabel('frequency [Hz]')
plt.colorbar(im, ax=axx[0])
axx[0].set_title('spectrogram')


# because of how they implemented WVT, the maximum frequency is half of
# the sampling Nyquist frequency, so 125 Hz instead of 250 Hz, and the sampling
# is 2 * dt instead of dt
f_wvd = np.fft.fftshift(np.fft.fftfreq(tfr_wvd.shape[0], d=2 * dt))
df_wvd = f_wvd[1]-f_wvd[0]  # the frequency step in the WVT
im = axx[1].imshow(np.fft.fftshift(tfr_wvd, axes=0), aspect='auto', origin='lower',
       extent=(ts[0] - dt/2, ts[-1] + dt/2,
               f_wvd[0]-df_wvd/2, f_wvd[-1]+df_wvd/2))
axx[1].set_xlabel('time [s]')
axx[1].set_ylabel('frequency [Hz]')
plt.colorbar(im, ax=axx[1])
axx[1].set_title('Wigner-Ville Transform')
plt.show()

Вот результат:

спектрограмма и преобразование Вигнера-Вилля

Поскольку сигнал настоящий, есть активность на положительных и отрицательных частотах, как и при БПФ. Кроме того, существует интерференция между двумя членами на частоте 0 (т. е. посередине между двумя). Это также то, что вы видели на вашем графике. То, что у вас было над средними линиями, — это отрицательные частоты, а то, что в самом верху, — это частота 0.

Для аналитического сигнала изображение проще. Здесь я создаю сигнал, используя:

signal = np.exp(1j * (ts-t0) * 2 * np.pi * freq) * np.exp(-(ts-t0)**2/(2*sigma**2))/np.sqrt(sigma)

А вот результирующая спектрограмма и WVT: спектрограмма и преобразование Вигнера-Вилля аналитического сигнала

Дайте мне знать, если вам нужны дополнительные разъяснения.

person Chachni    schedule 01.03.2021
comment
Отличный ответ, спасибо. Извините, что не ответил на ваш предыдущий вопрос, но прошло пару лет с тех пор, как у меня возникла эта проблема, и я действительно не помню, что с ней произошло. Я думаю, что по какой-то причине я отказался от этой линии анализа. Но это очень полезно для тех, кто работает с этим! - person Danf; 03.03.2021