【问题标题】:shift the elements of a vector by non-integer shift in matlab在matlab中通过非整数移位移动向量的元素
【发布时间】:2014-03-16 20:31:26
【问题描述】:

我想通过非整数移位来移动向量,线性插值似乎不是很准确,所以我试图通过以下使用傅里叶变换的代码使用 sinc 插值。

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)

如何克服这个问题,还有其他准确的方法吗?

【问题讨论】:

  • 其实我并不感到惊讶。对我来说,它看起来像预期的那样。我不确定是否有更好的方法来做到这一点,因此我无法对此发表声明。但是,当您进行整数移位时,您将获得频率箱作为整数的一部分,即f*s = -3:0.1:2.9 用于s=3,然后您可以确定每个样本x(函数 x)确实匹配一个箱。但是,当s 是分数(或实数)时,bin 变为非分数,这意味着x 中的每个值都不适合bin。这意味着您将有泄漏,这就是您在图表中看到的。

标签: matlab fft interpolation shift


【解决方案1】:

试试这个:

假设您移动了 3.5。弄清楚过采样值是多少(即什么值会将移位变为整数 - 在本例中为 2)。

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

这仍然有一些边缘振铃,但比您的 sinc 方法要少得多。正如评论中提到的,我不确定这是否是由于吉布斯现象造成的,因为您实际上是在截断或泄漏。

【讨论】:

    【解决方案2】:

    您可以像您一样使用fourier shift theorem 执行此操作,但要添加过滤。我问了一个类似的问题here。结果看起来“错误”的原因是您的输入向量不连续。您得到的结果确实是“正确的”(或至少 true)。

    您看到的问题称为Gibbs Ringing。您可以通过使用在其阶跃响应中没有振铃的低通滤波器(this wikipedia 链接很好地解释了解决方案)来减少这种极端情况。尝试使用和不使用 gaussian filter 的代码。这种伪影经常出现在 MRI 成像(以及许多其他信号处理情况)中,有时可以通过滤波得到缓解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 2016-09-01
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-01
      • 2012-09-18
      相关资源
      最近更新 更多