MatLab-смещение изображения с помощью FFT

Я хочу сдвинуть изображение (представленное 2D-матрицей), используя умножение его fft по exp (- j*2*pi*x*F), где x-смещение. У меня:

input=peaks(200);
H=fftshift(fft2(fftshift(input)));
x=19;
H=H*exp(-1i*x*2*pi*F);
IF_image=fftshift(ifft2(fftshift(H)));
imshow(IF_image)

но у меня возникли проблемы с идентификацией/представлением F в H[F], так как мой вход представляет собой 2-мерный массив. Как я мог это сделать? Желаемым выходом будет мое исходное изображение, смещенное по горизонтальной оси (на X единиц) в том же кадре, чтобы оно начиналось с x+1. В качестве примера:

если input=

1 2 3 4 5
6 7 8 9 0

и x=2, я хочу:

4 5 1 2 3
9 0 6 7 8

1 ответов


вы определили свойство для перевода / сдвига в 1D. Для 2D он немного отличается, но основан на том же принципе. Для достижения перевода в 2D это свойство translation / shift, которое определяется как:

enter image description here

x0,y0 будет сдвиг, который вы хотите ввести. Таким образом, положительное значение x0 сдвинет ваш 2D-сигнал вправо, в то время как отрицательное значение сдвинется влево. Аналогично, положительное значение y0 сдвинет ваше 2D-изображение вниз, в то время как отрицательное значение будет смещаться вверх.

поэтому, учитывая ваше преобразование Фурье в 2D, вам нужно будет добавить дополнительный член к экспоненте. Кроме того, вы должны Normalize исполнителя N или размер вашего 2D сигнала. Это предполагает, что ваш 2D-сигнал имеет одинаковое количество строк и столбцов. Если это не так, то вам придется забрать u*x0 и вы разделите на количество столбцов и v*y0 будет разделено на количество строк.
Теперь, причина, почему вы смущены F в приведенном выше коде, потому что вы не знаете, как определить это в 2D. Вы должны определить значение частоты для каждой точки в 2D сетки. Из-за вашего fftshift вызов, мы бы определили x и y значения между -100 и 99, так как ваш 2D-сигнал имеет размер 200 x 200, и это будет центрировать наш 2D-сигнал посередине. Это на самом деле то, что fftshift делающий. Аналогично,ifftshift отменяет центрирование, выполненное fftshift. Чтобы определить эти точки в 2D, я использую meshgrid. Как только вы определите эти точки, вы возьмете каждую пару (x,y) координаты, затем создайте комплексную экспоненту, как вы видите в вышеуказанном свойстве.

таким образом, ваш код должен быть изменен таким образом. Имейте в виду, что я избавился от избыточных fftshift и ifftshift вызовы в исходном коде. Вы бы назвали fft, тогда сделай fftshift в центре спектра. Я также изменил вашу переменную input до in, as input является функцией в MATLAB,и мы не хотим непреднамеренно затенять функцию переменной.

я также определил x shift, чтобы быть -35, и y shift, чтобы быть -50. Это будет означать, что результирующий сигнал сдвинется влево на 35, а вверх на 50.

таким образом:

in=peaks(200); %// Define input signal
H=fftshift(fft2(in)); %// Compute 2D Fourier Transform
x0=-35; %// Define shifts
y0=-50;

%// Define shift in frequency domain
[xF,yF] = meshgrid(-100:99,-100:99);

%// Perform the shift
H=H.*exp(-1i*2*pi.*(xF*x0+yF*y0)/200);

%// Find the inverse Fourier Transform
IF_image=ifft2(ifftshift(H));

%// Show the images
figure;
subplot(1,2,1);
imshow(in);
subplot(1,2,2);
imshow(real(IF_image));

обратите внимание, что Я показал реальные компонент результирующего изображения. Это связано с тем, что после обратного преобразования Фурье может быть некоторая численная неточность, и сложная часть сигнала на самом деле довольно мала. Мы можем игнорировать это, просто используя реальную составляющую сигнала.

это изображение, которое я получаю:

enter image description here

как вы можете видеть, изображение сдвинулось правильно,как это проверено свойством выше. Если вы хотите указать разные смены, вам просто нужно изменить x0 и y0 в соответствии с вашими вкусами. В вашем случае вы бы указали y0 = 0, потом x0 может быть все, что вы хотите, как вы хотите, горизонтальный перевод.