Tôi đang cố gắng hiểu một cách khái niệm những gì đang xảy ra khi các Biến đổi Fourier chuyển tiếp và nghịch đảo (STFT) được áp dụng cho tín hiệu miền thời gian rời rạc. Tôi đã tìm thấy bài báo kinh điển của Allen và Rabiner ( 1977 ), cũng như một bài viết trên Wikipedia ( liên kết ). Tôi tin rằng cũng có một bài viết hay khác được tìm thấy ở đây .
Tôi quan tâm đến việc tính toán biến đổi Gabor, không gì khác hơn là STFT với cửa sổ Gaussian.
Đây là những gì tôi hiểu về STFT chuyển tiếp :
- Một chuỗi con được chọn từ tín hiệu, bao gồm các yếu tố miền thời gian.
- Chuỗi con được nhân với một hàm cửa sổ bằng cách nhân từng điểm trong miền thời gian.
- Chuỗi con được nhân lên được đưa vào miền tần số bằng cách sử dụng FFT.
- Bằng cách chọn các chuỗi con chồng chéo liên tiếp và lặp lại quy trình ở trên, chúng ta có được một ma trận với m hàng và n cột. Mỗi cột là chuỗi con được tính toán tại một thời điểm nhất định. Điều này có thể được sử dụng để tính toán một phổ.
Tuy nhiên, đối với STFT nghịch đảo , các bài báo nói về một tổng kết trên các phần phân tích chồng chéo. Tôi thấy rất khó khăn để hình dung những gì đang thực sự xảy ra ở đây. Tôi phải làm gì để có thể tính toán STFT nghịch đảo (theo thứ tự từng bước như trên)?
Chuyển tiếp STFT
Tôi đã tạo một bản vẽ cho thấy những gì tôi nghĩ đang diễn ra cho STFT phía trước. Điều tôi không hiểu là làm thế nào để tập hợp từng chuỗi con để tôi lấy lại chuỗi thời gian ban đầu. Ai đó có thể sửa đổi bản vẽ này hoặc đưa ra một phương trình cho thấy cách thêm các chuỗi con?
Biến đổi nghịch đảo
Đây là những gì tôi hiểu về biến đổi nghịch đảo. Mỗi cửa sổ liên tiếp được đưa trở lại miền thời gian bằng IFFT. Sau đó, mỗi cửa sổ được thay đổi theo kích thước bước và được thêm vào kết quả của ca trước đó. Sơ đồ sau cho thấy quá trình này. Đầu ra tổng là tín hiệu miền thời gian.
Mã ví dụ
Mã Matlab sau đây tạo tín hiệu miền thời gian tổng hợp, sau đó kiểm tra quy trình STFT, chứng minh rằng nghịch đảo là kép của biến đổi chuyển tiếp, trong lỗi tắt số tròn. Đầu và cuối của tín hiệu được đệm bằng 0 để đảm bảo rằng tâm của cửa sổ có thể được đặt ở các phần tử đầu tiên và cuối cùng của tín hiệu miền thời gian.
LƯU Ý rằng theo Allen và Rabiner (1977), nếu phép nhân xảy ra trong miền tần số để thay đổi tần số đáp ứng, độ dài của cửa sổ phân tích phải bằng hoặc lớn hơn điểm, trong đó là đáp ứng bộ lọc . Chiều dài được mở rộng bằng cách đệm không. Mã kiểm tra chỉ đơn giản cho thấy rằng nghịch đảo là kép của biến đổi chuyển tiếp. Chiều dài phải được mở rộng để ngăn chặn một tổ hợp tròn.N 0
% 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);