2014-02-17 61 views
2

我想移動一個向量非整數移位,線性插值似乎不是很準確,所以我試圖用sinc插值由以下使用傅里葉變換的代碼。在matlab中移動一個向量的非整數移位

function y = fshift(x,s) 
% FSHIFT Fractional circular shift 
% Syntax: 
% 
%  >> y = fshift(x,s) 
% 
% FSHIFT circularly shifts the elements of vector x by a (possibly 
% non-integer) number of elements s. FSHIFT works by applying a linear 
% phase in the spectrum domain and is equivalent to CIRCSHIFT for integer 
% values of argument s (to machine precision). 


needtr = 0; if size(x,1) == 1; x = x(:); needtr = 1; end; 
N = size(x,1); 
r = floor(N/2)+1; f = ((1:N)-r)/(N/2); 
p = exp(-j*s*pi*f)'; 
y = ifft(fft(x).*ifftshift(p)); if isreal(x); y = real(y); end; 
if needtr; y = y.'; end; 

有代碼中沒有問題時,我轉移由整數偏移的方波,但是當變速是非整數的輸出從顯著波動 即患有,

s=[zeros(1,20) ones(1,20) zeros(1,20)]; 
b=fshift(s,3.5); 
stem(b) 

如何克服這個問題,有沒有其他準確的方法?

+0

其實我並不感到驚訝。對我來說,它看起來像預期的。我不確定是否有更好的方法來做到這一點,因爲我不能對此做出發音。然而,當你做一個整數移位時,你將有一個整數部分的頻率點,也就是's = 3的'f * s = -3:0.1:2.9',那麼你可以確定每個樣本' x'(函數x)確實匹配一個bin。然而,當's'是一個分數(或一個實數)時,分箱變爲非分數,這意味着'x'中的每個值都不適合分箱。這意味着你將有泄漏,這就是你在圖表中看到的。 – patrik

回答

0

試試這個:

假設你正在移動3.5。找出過採樣值是什麼(即什麼值會改變整數 - 在這種情況下,它是2)。

ov = 2; 
a = 3.5*ov; 
y = downsample(circshift(interp(s,2).', -a),ov); 

這仍然有一些在邊緣振鈴,但比你的正弦方法少得多。我不確定這是否是由於gibbs現象造成的,因爲您基本上是截斷或泄漏,正如評論中所述。

0

你可以像這樣做fourier shift theorem,但是增加了過濾。我問了一個類似的問題here。結果看起來「錯誤」的原因是因爲您的輸入向量不連續。你得到的結果真的是'正確的'(或至少true)。

您所看到的問題稱爲Gibbs Ringing。您可以通過使用低通濾波器(this維基百科鏈接解釋相當好的解決方案),使其在階躍響應中沒有振鈴,從而使其不那麼極端。嘗試使用或不使用gaussian filter。這種僞影常常在MRI成像(以及許多其他信號處理情況)中看到,有時通過濾波來緩解。