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, которое определяется как:
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));
обратите внимание, что Я показал реальные компонент результирующего изображения. Это связано с тем, что после обратного преобразования Фурье может быть некоторая численная неточность, и сложная часть сигнала на самом деле довольно мала. Мы можем игнорировать это, просто используя реальную составляющую сигнала.
это изображение, которое я получаю:
как вы можете видеть, изображение сдвинулось правильно,как это проверено свойством выше. Если вы хотите указать разные смены, вам просто нужно изменить x0
и y0
в соответствии с вашими вкусами. В вашем случае вы бы указали y0 = 0
, потом x0
может быть все, что вы хотите, как вы хотите, горизонтальный перевод.