为什么在Matlab中使用ifft2时图像会移位

问题描述 投票:1回答:1

我正在使用FFT实现2D卷积。这是我的代码:

img = im2single(imread('dog.bmp'));
filter = fspecial('gaussian', 53, 3);
F = fft2(img);
mask = fft2(filter, size(img, 1), size(img, 2));
filtered_img = ifft2(F .* mask);
imshow(real(filtered_img));

这是原始图像:

enter image description here

结果在这里:enter image description here

为什么会这样?我该如何解决?请帮我。非常感谢。

matlab image-processing signal-processing fft convolution
1个回答
0
投票

问题是您的滤波器的频率响应,

filter = fspecial('gaussian', 53, 3);

相对于坐标原点

已移位。要对此进行检查,请使用

imagesc(filter)

enter image description here

您可以看到filter在坐标2727而不是在11处具有最大值。偏移量可以(对于奇数大小的脉冲响应)计算为(size(filter)-1)/2,在这种情况下为[26, 26]

下面,我将使用此图像作为示例:

img = im2single(imread('cameraman.tif')); % size [256, 256]

稍后,在代码中,当您使用可选的第二和第三个参数调用fft2时,

mask = fft2(filter, size(img, 1), size(img, 2));

第一个输入为隐式右-填充,每个维中都有零以匹配指定的大小,在我的示例256中为img。您可以通过绘制其逆变换来检查它:

imagesc(real(ifft2(mask)))

enter image description here


之后,您的代码将原始图像的变换与滤波器的脉冲响应相乘,然后变换回去。这等效于原始图像img和冲激响应filter圆周卷积。现在,由于后者在两个维度上相对于原点偏移了26个样本,因此在输出信号中产生circular shiftThis是您观察到的问题。


为解决这个问题,您需要在考虑填充的情况下纠正偏移。

最简单的方法是手动进行填充(而不是让fft2隐式地进行填充,并且同时将(size(filter)-1)/2样本在每个维度上向左循环移位:

filter_corrected = filter; % initiallize
filter_corrected(size(img, 1), size(img, 2)) = 0; % this right-pads with zeros
shift = (size(filter)-1)/2; % as seen above
filter_corrected = filter_corrected( ...
    mod((1:end)+shift(1)-1, end)+1, ...
    mod((1:end)+shift(2)-1, end)+1); % this undoes the circular shifting

现在校正后的脉冲响应filter_corrected具有所需的大小,并且最大值为11

imagesc(filter_corrected)

enter image description here

因此您可以在其余的代码中使用它:

F = fft2(img);
mask = fft2(filter_corrected, size(img, 1), size(img, 2));
filtered_img = ifft2(F .* mask);
imshow(real(filtered_img));

使用此图像,原始图像和过滤后的图像是>

imshow(img)
figure
imshow(real(filtered_img))

enter image description here

enter image description here


作为附加说明

  • 观察过滤过程如何使图像下部的一点(摄影师的腿)“溢出”到上部。这是您用于过滤的方法(在DFT域中进行乘法)的结果,该方法与原始域中的卷积相对应。最好不要使用filter作为变量名,因为这样会以相同的名称遮盖内置函数。
© www.soinside.com 2019 - 2024. All rights reserved.