【问题标题】:MatLab - Shifting an image using FFTMatLab - 使用 FFT 移动图像
【发布时间】:2014-11-07 18:59:39
【问题描述】:

我想使用其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

【问题讨论】:

  • 只是说,使用circshift不是更简单吗?
  • 是的。但原则上,这可以使用我感兴趣的所描述的方法来完成。 (:
  • @CeciliaGuerra - 我同意circshift,但我假设您这样做是为了演示傅立叶变换的平移/移位属性。不管怎样,我已经写了一个答案。
  • circshift 仅在您移动整数像素时有帮助

标签: image matlab image-processing fft ifft


【解决方案1】:

您确定了一维平移/移动的属性。对于 2D,它略有不同,但基于相同的原理。实现2D平移,这是translation/shift属性,定义为:

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

因此,鉴于您的二维傅里叶变换,您需要在指数中添加一个附加项。此外,您必须N 或 2D 信号的大小进行标准化。这是假设您的 2D 信号具有相同的行数和列数。如果不是这种情况,那么您将不得不采用 u*x0 并除以列数,而 v*y0 将除以行数。
现在,您对上述代码中的F 感到困惑的原因是您不确定如何在 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 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));

请注意,我显示了结果图像的 真实 组件。这是因为一旦你进行傅里叶逆变换,可能会有一些数值不精确,而且信号的复杂部分实际上非常小。我们可以通过只使用信号的实部来忽略这一点。

这是我得到的图像:

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

【讨论】:

  • @Sandino - 不敢相信我没有注意到那个错字。我很久以前就回答了这个问题。谢谢指正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
相关资源
最近更新 更多