我正在使用 FFT 2D 创建索贝尔图像。效果很好!但有一个问题是顶部和左侧有两行是重复的。这是因为索贝尔内核
K_y
和 K_x
。它们并不以 fft2
算法为中心,这就是为什么我在左侧和顶部得到这样的边框的原因。
如果
K_y
和K_x
完全集中在m/2
和n/2
,那么我将得到四个重复的图像。所以我必须将索贝尔内核放在 (0,0)
的中心,但我已经这样做了。
% Get X
X = imread('image.png');
% Gray scaled image
if(size(X, 3) > 1)
X = rgb2gray(X);
end
% Create kernels for X-direction and Y-direction
K_x = [-1 0 1; -2 0 2; -1 0 1];
K_y = [-1 -2 -1; 0 0 0; 1 2 1];
% Do conv2 with FFT
Gx = conv2_fft(X, K_x);
Gy = conv2_fft(X, K_y);
% Compute the gradients
G = sqrt(Gx.^2 + Gy.^2);
% Compute the orientations
O = atan2d(Gy, Gx);
end
function G = conv2_fft(X, K)
% Create kernel
[m, n] = size(X);
kernel = zeros(m, n);
[m, n] = size(K);
kernel(1:m, 1:n) = K;
% Do FFT2 on X and kernel
A = fft2(X);
B = fft2(kernel);
% Compute the convolutional matrix - abs to remove zero imaginary numbers
G = abs(ifft2(A.*B));
end
问题:
如何通过选择合适的内核来使 Sobel 内核居中?
这就是答案。正如克里斯·卢恩戈所说。内核必须移动。
function G = conv2_fft(X, K)
% Create kernel
[m, n] = size(X);
kernel = zeros(m, n);
[m, n] = size(K);
kernel(1:m-1, 1:n-1) = K(2:3, 2:3);
kernel(end, 1:n-1) = K(1, 2:3);
kernel(1:m-1, end) = K(2:3, 1);
kernel(end, end) = K(1,1);
% Do FFT2 on X and kernel
A = fft2(X);
B = fft2(kernel);
% Compute the convolutional matrix - abs to remove zero imaginary numbers
G = abs(ifft2(A.*B));
end
结果: