MatLab - 使用FFT移动图像

时间:2014-09-13 21:33:54

标签: image matlab image-processing fft ifft

我希望使用其fft与exp(-j * 2 * pi * x * F)的乘法来移动图像(由2D矩阵表示),其中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)

但由于我的输入是二维数组,因此我在识别/表示H [F]中的F时遇到了麻烦。我怎么能这样做? 所需的输出将是我的原始图像在同一帧中在水平轴上移位(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 个答案:

答案 0 :(得分:12)

您在1D中确定了翻译/转移的属性。对于2D,它略有不同,但基于相同的原理。要在2D中实现平移,这是平移/移位属性,定义为:

enter image description here

x0,y0将是您想要介绍的转变。因此,x0的正值会使您的2D信号向右移动,而负值会向左移动。同样,y0的正值会使您的2D图像向下移动,而负值会向上移动。

因此,给定2D中的傅里叶变换,您需要为指数添加一个附加项。此外,您必须N或2D信号的大小进行标准化。这假设您的2D信号具有相同的行数和列数。如果不是这种情况,则必须采用u*x0,然后除以列数,v*y0除以行数。
现在,您在上面的代码中对F感到困惑的原因是因为您不确定如何在2D中定义它。您必须为2D网格中的每个点定义频率值 。由于您的fftshift调用,我们会定义-100到99之间的xy值,因为您的2D信号大小为200 x 200,这将使我们的2D信号居中在中间。这实际上是fftshift正在做的事情。同样,ifftshift撤消fftshift完成的居中。要在2D中定义这些点,我使用meshgrid。定义这些点后,您将获取每对(x,y)坐标,然后创建复杂的指数,如上面的属性中所示。

因此,您的代码必须以这种方式进行修改。请记住,我在原始代码中删除了多余的fftshiftifftshift调用。您可以拨打fft,然后执行fftshift以使频谱居中。我还将变量input更改为in,因为input是MATLAB中的函数,我们不希望无意中使用变量隐藏函数。

我还将x转换定义为-35,y转换为-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

正如您所看到的,图像确实已经正确移动,正如上面所看到的属性所证实的那样。如果您想指定不同的班次,只需更改x0y0以符合您的口味。在您的情况下,您可以指定y0 = 0,然后x0可以是您想要的任何水平翻译。