2014-02-17 3 views
2

Я хочу сместить вектор по нецелому сдвигу, линейная интерполяция кажется не очень точной, поэтому я пытаюсь использовать интерполяцию следующим образом код, который использует преобразование Фурье.смещение элементов вектора по нецелому сдвигу в 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

На самом деле я действительно не удивлен. Для меня это похоже на ожидаемый. Я не уверен, есть ли лучший способ сделать это, поэтому я не могу произнести про это. Однако, когда вы выполняете целочисленный сдвиг, у вас будут частотные бункеры как часть целого числа, то есть 'f * s = -3: 0.1: 2.9' для' s = 3', тогда вы можете быть уверены, что каждый образец ' x' (функция x) действительно соответствует bin. Однако, когда 's' является дробью (или реальным числом), бины становятся нечетными, дробными, что означает, что каждое значение в' x' не помещается в корзину. Это означает, что у вас будет утечка, и это то, что вы видите на графике. – patrik

ответ

0

Попробуйте следующее:

Предположим, вы перешли на 3.5. Выясните, что такое значение избыточной выборки (то есть какое значение изменит сдвиг на целое число - в данном случае это 2).

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

У этого по-прежнему есть некоторые звонки по краям, но гораздо меньше, чем ваш подход. Я не уверен, что это связано с феноменом гиббсов, поскольку вы по существу усекаетесь или просачиваетесь, как указано в комментарии.

0

Вы можете сделать это с помощью fourier shift theorem, как и вы, но с дополнительной фильтрацией. Я задал аналогичный вопрос here. Причина, по которой результат выглядит «неправильно», заключается в том, что ваш входной вектор не является непрерывным. Результат, который вы получаете, действительно «правильный» (или по крайней мере true).

Проблема, которую вы видите, называется Gibbs Ringing. Вы можете сделать это менее экстремальным, используя фильтр нижних частот (this wikipedia link очень хорошо объясняет решение), который не реагирует на ответ шага. Попробуйте код с gaussian filter и без него. Этот артефакт часто встречается в МРТ-визуализации (и во многих других ситуациях обработки сигналов), и иногда он облегчается фильтрацией.

Смежные вопросы