“零阶段”零填充的优点

信息处理 fft 信号分析 零填充
2022-02-13 21:24:38

我了解在 FFT 之前对有限信号进行零填充的原因。

但是,我正在阅读这本书 ( http://www.dsprelated.com/dspbooks/sasp/Zero_Phase_Zero_Padding.html ),其中的主题是零相位零填充。

上图:加窗有限信号。 下图:同一信号的零相位零填充版本。

Top image: windowed finite signal. 
Bottom image: Zero Phase Zero Padded version of the same signal.

零相位零填充优于“常规”零填充(无论是在有限信号之前、之后还是两端添加零)对我来说并不明显。它的优势是什么?

编辑

为了帮助将来可能有这个问题的其他人,我在这里添加我的评论和我尝试过的事情,以便更多地理解这一点 - 希望这将为将来有这个问题的人节省时间。

在@matt-l 发表评论之后,我编写了一个 matlab 脚本,用于查看以 3 种方式(signal000000、000signal000 和 nal000000sig)填充零的对称信号的幅度和相位响应的差异。第三个是零相位零填充。

情况 3 中频率响应的虚部非常接近 0(在本底噪声的数量级上 - Matlab 中的 eps)。然而,展开阶段仍然存在——正如马特指出的那样,这可能是由于数字问题。

Matlab 绘图

高分辨率

我写的脚本是:

NSIG = 128; % Signal length
NFFT = 512; % FFT length

% Make signal
n = 0:NSIG - 1;
w1 = pi/8; 
w2 = 3*pi/4; % w1 and w2 are normalized frequencies of the signal

signal = 0.5*cos(w1*n) + cos(w2*n);

% Make signal symmetric about NSIG/2
signal = [fliplr(signal), signal(2:end)]; % Make signal symmetric
NSIG = length(signal);

% Window the input
window = ones (size(signal));
% window = hanning(NSIG)';
raw_in = signal.*window;

%% A. Zero pad at the end only
NZERO = NFFT-NSIG;
in = [raw_in, zeros(1,NFFT-NSIG)];
show_spec1 = fft (in);

%% B. Zero pad on both sides
in = [zeros(1, floor(NZERO/2)), raw_in, zeros(1,ceil(NZERO/2))];
show_spec2 = fft (in);

%% C. Zero phase zero pad
in = [raw_in(floor(NSIG/2)+1:NSIG), zeros(1,NZERO), raw_in(1:floor(NSIG/2))];
show_spec3 = fft (in);

% Prepare to plot
fs = 500;
fres = fs/NFFT;     % Freq resolution
w = fres.*([0:NFFT/2, -NFFT/2+1:-1]);
figure;

%% PLOTS
titleStr = 'A. - s i g n a l 0 0 0 0 0 0 -';
h(1) = subplot (3,2,1); stem (w, abs(show_spec1),'.-'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Magnitude');
h(2) = subplot (3,2,2); plot (w, unwrap(angle(show_spec1)),'r'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Unwrapped Phase');

titleStr = 'B. - 0 0 0 s i g n a l 0 0 0 -';
h(3) = subplot (3,2,3); stem (w, abs(show_spec2),'.-'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Magnitude');
h(4) = subplot (3,2,4); plot (w, unwrap(angle(show_spec2)),'r'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Unwrapped Phase');

titleStr = 'C. - n a l 0 0 0 0 0 0 s i g -';
h(5) = subplot (3,2,5); stem (w, abs(show_spec3),'.-'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Magnitude');
h(6) = subplot (3,2,6); plot (w, unwrap(angle(show_spec3)),'r'); axis tight; title (titleStr); grid on;
xlabel('Frequency (Hz)'); ylabel('Unwrapped Phase');
2个回答

这只是在零填充后获得对称信号。取一个对称信号(时间索引)并附加零。由于用作 DFT 输入的时间信号的隐含周期性,将所有零添加到对称信号的右侧、左侧或两端都没有关系。在任何情况下,由于 DFT/FFT 假设缓冲区中的第一个样本是时间原点,因此 FFT 的输入向量需要安排为n=0

[right half of the signal | left half of the signal]

这基本上是在之间的周期性连续补零信号的一个周期,其中是 FFT 长度,即补零后的信号长度。请注意,现在所有零都位于要转换的向量的中间。如果操作正确,FFT 的结果将是纯实值(除了数值误差)。如果信号是不对称的,它的 FFT 将是纯虚数。n=0n=N1N

[新回复,因为我无法编辑我以前的评论。]

零相位填充的原因确实是为了在零填充之后保持信号尽可能对称。我想补充一点:确保零相位填充信号的大小为奇数,以消除不需要的移位失真。