Algoritmo di inversione di trasformata di Fourier a breve termine descritto a parole


20

Sto cercando di capire concettualmente cosa sta succedendo quando le trasformazioni di Fourier a breve termine (STFT) in avanti e inversa vengono applicate a un segnale nel dominio del tempo discreto. Ho trovato il classico articolo di Allen e Rabiner ( 1977 ), nonché un articolo di Wikipedia ( link ). Credo che ci sia anche un altro buon articolo qui .

Sono interessato a calcolare la trasformazione di Gabor, che non è altro che la STFT con una finestra gaussiana.

Questo è quello che capisco sul futuro STFT:

  1. Una sottosequenza viene selezionata dal segnale, composta da elementi nel dominio del tempo.
  2. La sottosequenza viene moltiplicata per una funzione di finestra utilizzando la moltiplicazione punto per punto nel dominio del tempo.
  3. La sottosequenza moltiplicata viene portata nel dominio della frequenza usando FFT.
  4. Selezionando le successive sequenze sovrapposte e ripetendo la procedura sopra, otteniamo una matrice con m righe e n colonne. Ogni colonna è la sottosequenza calcolata in un determinato momento. Questo può essere usato per calcolare uno spettrogramma.

Tuttavia, per la STFT inversa , i documenti parlano di una sommatoria sulle sezioni di analisi sovrapposte. Trovo molto stimolante visualizzare ciò che sta realmente accadendo qui. Cosa devo fare per poter calcolare lo STFT inverso (in ordine graduale come sopra)?

Avanti STFT

Ho creato un disegno che mostra ciò che penso stia succedendo per la STFT. Quello che non capisco è come assemblare ciascuna delle sotto-sequenze in modo da recuperare la sequenza temporale originale. Qualcuno potrebbe modificare questo disegno o fornire un'equazione che mostra come vengono aggiunte le sub-sequenze?Trasformazione in avanti

Trasformazione inversa

Ecco cosa ho capito della trasformazione inversa. Ogni finestra successiva viene reinserita nel dominio del tempo usando l'IFFT. Quindi ogni finestra viene spostata in base alla dimensione del passo e aggiunta al risultato del turno precedente. Il diagramma seguente mostra questo processo. L'output sommato è il segnale del dominio del tempo.

Trasformazione inversa

Esempio di codice

Il seguente codice Matlab genera un segnale nel dominio del tempo sintetico, quindi verifica il processo STFT, dimostrando che l'inverso è il doppio della trasformazione in avanti, all'interno di un errore di arrotondamento numerico. L'inizio e la fine del segnale sono a zero, per garantire che il centro della finestra possa trovarsi nel primo e nell'ultimo elemento del segnale nel dominio del tempo.

N+N0-1N0

% The code computes the STFT (Gabor transform) with step size = 1
% This is most useful when modifications of the signal is required in
% the frequency domain

% The Gabor transform is a STFT with a Gaussian window (w_t in the code)

% written by Nicholas Kinar

% Reference:
% [1] J. B. Allen and L. R. Rabiner, 
% “A unified approach to short-time Fourier analysis and synthesis,” 
% Proceedings of the IEEE, vol. 65, no. 11, pp. 1558 – 1564, Nov. 1977.

% generate the signal
mm = 8192;                  % signal points
t = linspace(0,1,mm);       % time axis

dt = t(2) - t(1);           % timestep t
wSize = 101;                % window size


% generate time-domain test function
% See pg. 156
% J. S. Walker, A Primer on Wavelets and Their Scientific Applications, 
% 2nd ed., Updated and fully rev. Boca Raton: Chapman & Hall/CRC, 2008.
% http://www.uwec.edu/walkerjs/primer/Ch5extract.pdf
term1 = exp(-400 .* (t - 0.2).^2);
term2 = sin(1024 .* pi .* t);
term3 = exp(-400.*(t- 0.5).^2);
term4 = cos(2048 .* pi .* t);
term5 = exp(-400 .* (t-0.7).^2);
term6 = sin(512.*pi.*t) - cos(3072.*pi.*t);
u = term1.*term2  + term3.*term4 + term5.*term6; % time domain signal
u = u';

figure;
plot(u)

Nmid = (wSize - 1) / 2 + 1;    % midway point in the window
hN = Nmid - 1;                 % number on each side of center point       


% stores the output of the Gabor transform in the frequency domain
% each column is the FFT output
Umat = zeros(wSize, mm);     


% generate the Gaussian window 
% [1] Y. Wang, Seismic inverse Q filtering. Blackwell Pub., 2008.
% pg. 123.
T = dt * hN;                    % half-width
sp = linspace(dt, T, hN); 
targ = [-sp(end:-1:1) 0 sp];    % this is t - tau
term1 = -((2 .* targ) ./ T).^2;
term2 = exp(term1);
term3 = 2 / (T * sqrt(pi));
w_t = term3 .* term2;
wt_sum = sum ( w_t ); % sum of the wavelet


% sliding window code
% NOTE that the beginning and end of the sequence
% are padded with zeros 
for Ntau = 1:mm

    % case #1: pad the beginning with zeros
    if( Ntau <= Nmid )
        diff = Nmid - Ntau;
        u_sub = [zeros(diff,1); u(1:hN+Ntau)];
    end

    % case #2: simply extract the window in the middle
    if (Ntau < mm-hN+1 && Ntau > Nmid)
        u_sub = u(Ntau-hN:Ntau+hN);
    end

    % case #3: less than the end
    if(Ntau >= mm-hN+1)
        diff = mm - Ntau;
        adiff = hN - diff;
        u_sub = [ u(Ntau-hN:Ntau+diff);  zeros(adiff,1)]; 
    end   

    % windowed trace segment
    % multiplication in time domain with
    % Gaussian window  function
    u_tau_omega = u_sub .* w_t';

    % segment in Fourier domain
    % NOTE that this must be padded to prevent
    % circular convolution if some sort of multiplication
    % occurs in the frequency domain
    U = fft( u_tau_omega );

    % make an assignment to each trace
    % in the output matrix
    Umat(:,Ntau) = U;

end

% By here, Umat contains the STFT (Gabor transform)

% Notice how the Fourier transform is symmetrical 
% (we only need the first N/2+1
% points, but I've plotted the full transform here
figure;
imagesc( (abs(Umat)).^2 )


% now let's try to get back the original signal from the transformed
% signal

% use IFFT on matrix along the cols
us = zeros(wSize,mm);
for i = 1:mm 
    us(:,i) = ifft(Umat(:,i));
end

figure;
imagesc( us );

% create a vector that is the same size as the original signal,
% but allows for the zero padding at the beginning and the end of the time
% domain sequence
Nuu = hN + mm + hN;
uu = zeros(1, Nuu);

% add each one of the windows to each other, progressively shifting the
% sequence forward 
cc = 1; 
for i = 1:mm
   uu(cc:cc+wSize-1) = us(:,i) + uu(cc:cc+wSize-1)';
   cc = cc + 1;
end

% trim the beginning and end of uu 
% NOTE that this could probably be done in a more efficient manner
% but it is easiest to do here

% Divide by the sum of the window 
% see Equation 4.4 of paper by Allen and Rabiner (1977)
% We don't need to divide by L, the FFT transform size since 
% Matlab has already taken care of it 
uu2 = uu(hN+1:end-hN) ./ (wt_sum); 

figure;
plot(uu2)

% Compare the differences bewteen the original and the reconstructed
% signals.  There will be some small difference due to round-off error
% since floating point numbers are not exact
dd = u - uu2';

figure;
plot(dd);

2
Ottima domanda - ma come hai fatto a realizzare questi diagrammi così velocemente al volo? ...
Spacey

2
Ho usato Adobe Illustrator per i diagrammi e Mathtype per i personaggi greci.
Nicholas Kinar,

1
"Sono interessato a calcolare la trasformazione di Gabor, che non è altro che la STFT con una finestra gaussiana." Ricorda che la trasformazione di Gabor è un integrale continuo e che le finestre gaussiane si estendono all'infinito. Le implementazioni tipiche di STFT utilizzano blocchi sovrapposti discreti e devono utilizzare finestre di lunghezza finita.
endolith

Grazie per averlo sottolineato, endolith. Tendo a pensare in modo molto discreto durante l'elaborazione del segnale.
Nicholas Kinar,

Risposte:


11

La coppia di trasformazioni STFT può essere caratterizzata da 4 diversi parametri:

  1. Dimensione FFT (N)
  2. Dimensione del gradino (M)
  3. Finestra di analisi (dimensione N)
  4. Finestra di sintesi (dimensione N)

Il processo è il seguente:

  1. Prendi N (dimensioni fft) campioni dalla posizione di input corrente
  2. Applica finestra di analisi
  3. Fai la FFT
  4. Fai quello che vuoi fare nel dominio della frequenza
  5. FFT inversa
  6. Applica finestra di sintesi
  7. Aggiungi all'output nella posizione di output corrente
  8. Avanzare la posizione di input e output di M (step size) campioni

L'algoritmo di sovrapposizione add è un buon esempio per questo. In questo caso la dimensione del passo è N, la dimensione FFT è 2 * N, la finestra di analisi è rettangolare con N quelle seguite da N zeri e le finestre di sintesi sono semplicemente tutte.

Ci sono molte altre scelte per questo e in determinate condizioni il trasferimento in avanti / inverso si sta completamente ricostruendo (cioè è possibile ottenere il segnale originale indietro).

Il punto chiave qui è che ogni campione di output riceve tipicamente contributi additivi da più di una FFT inversa. L'output deve essere accumulato su più frame. Il numero di frame che contribuiscono è semplicemente dato dalla dimensione FFT divisa per la dimensione del passo (arrotondata per eccesso, se necessario).


Grazie mille per la tua risposta perspicace. Comprendo il metodo di sovrapposizione-aggiunta. Cosa devo usare per la finestra di sintesi? C'è un'equazione? Se conosco la funzione della finestra di analisi (come una finestra gaussiana), come posso calcolare la finestra di sintesi? Capisco come il metodo overlap-add viene utilizzato per la convoluzione, ma non capisco come viene utilizzato per la STFT. Se la dimensione del passaggio è step = 1, come posso aggiungere i frame insieme? C'è un'equazione?
Nicholas Kinar,

Se la funzione della finestra di analisi è centrata su ciascun campione con step size step = 1, devo zero-pad l'inizio e la fine della sequenza del dominio del tempo in modo che il centro della finestra sia centrato su ciascun campione (incluso il primo e l'ultimo campioni nella sequenza nel dominio del tempo)?
Nicholas Kinar,

È possibile scegliere la dimensione del passo, la dimensione del fft, le finestre di analisi e sintesi in base alle esigenze specifiche dell'applicazione. Un esempio è la dimensione del gradino N, la dimensione FFT 2 * N, l'analisi delle analisi, la sintesi di tutti. Puoi modificarlo per analizzare sqrt (hanning) e synthesis sqrt (hanning). O uno funzionerà. Si riduce a ciò che fai nel dominio della frequenza e che tipo di artefatti come alias del dominio del tempo potresti creare.
Hilmar,

@Hilmar: Devo essere in grado di apportare modifiche al dominio della frequenza al segnale, quindi prendere l'IFFT per ottenere un segnale nel dominio del tempo. Vorrei minimizzare l'aliasing nel dominio del tempo. Non riesco ancora a capire come riportare ciascuna sotto-sequenza nel dominio del tempo e poi sommarle.
Nicholas Kinar,

Ho scritto del codice di prova e poi ho aggiornato la mia domanda originale.
Nicholas Kinar,

2

Sette anni dopo che questa domanda è stata sollevata per la prima volta, mi imbatto in questa confusione simile a @ Nicholas Kinar. Qui vorrei fornire alcune idee e spiegazioni percettive personali "non ufficiali" e "correttezza non completamente assicurate".

Il titolo delle seguenti dichiarazioni è esagerato per una migliore intelligibilità.

  1. Il processo forward di STFT non ha davvero lo scopo di preservare il segnale originale.
    • Quando si utilizza STFT con una finestra non banale (non tutte), il segnale di ingresso a FFT è una versione inclinata / allungata del frammento di segnale originale.
    • Questo è utile per l'estrazione di funzionalità, in cui vengono filtrati i dati inutili / ridondanti. Come nel rilevamento delle sillabe, non tutti i dati temporali sono necessari per rilevare alcuni toni in un discorso.
    • Il picco nel vettore della finestra rappresenta la minoranza delle posizioni in un segnale audio a cui gli algoritmi dovrebbero prestare attenzione.
  2. Quindi il risultato grezzo della STFT inversa potrebbe essere qualcosa che non possiamo aspettarci intuitivamente.
    • Dovrebbero essere i frammenti del segnale a finestre che dovrebbero apparire come l'ifft delle funzionalità STFT.
  3. Per ottenere i frammenti di segnale originali senza finestre, è possibile applicare una finestra inversa all'output non elaborato di ifft.
    • È facile progettare una funzione di mappatura che può annullare l'effetto finestra hann / hamming.
  4. La finestra di sintesi viene quindi coinvolta per gestire la sovrapposizione della frammentazione temporale
    • Poiché i frammenti di segnale originali senza finestre possono essere visti come già ottenuti, è possibile utilizzare qualsiasi "ponderazione di transizione" per interpolare le parti sovrapposte.
  5. Se si desidera considerare che il fft di un discorso a finestra potrebbe meno rispettare i segnali deboli ma adorare quei segnali potenti, allora potrebbe esserci un modo per progettare le corrispondenti finestre di sintesi.
  6. Inoltre, un algoritmo di generazione della finestra di sintesi diretta può essere dato applicando i seguenti principi:
    • pesare più in alto le posizioni nella finestra di sintesi se il valore della finestra di analisi per questa posizione è alto, confrontandolo con altri frammenti che si sovrappongono a questa posizione.
    • il peso riduce le posizioni nella finestra di sintesi se il valore della finestra di analisi per questa posizione è basso e altri frammenti sovrapposti onorano maggiormente questa posizione con un valore della finestra di analisi più grande.

1
Queste sono dichiarazioni interessanti che possono sicuramente aiutare a incoraggiare a pensare alla STFT.
Nicholas Kinar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.