当我尝试在matlab中验证卷积定理时,为什么我得到了一个大的MSE?

时间:2017-10-18 05:45:56

标签: matlab convolution

我想在matlab中验证卷积定理。

首先,我做了2D高斯的二维离散卷积 图像灰度图(x,y)。

其次,我计算了傅里叶变换 相同的2D高斯和原始图像。然后执行标量乘法 在这两个傅立叶变换中,接着是结果的逆傅里叶变换。

最后,我将计算两个结果之间的MSE。但是,我发现错误是800 +。

这是我的代码:

[row, col] = size(graymap);
[row_2, col_2] = size(z);
result = zeros(row, col);
for i = 1: col
    for j = 1:row
    accumulation_value = 0;
    for k = -4:4
        for h = -4:4
            if ((i+k > 0 && i+k < col + 1) && (j+h > 0 && j+h < row + 1))
                value_image = double(graymap(i+k, j+h));
            else
                value_image = 0;
            end
            accumulation_value = accumulation_value + value_image * double(z(5 + k, 5 + h));
            weighted_sum = weighted_sum + z(5 + k, 5 + h);
        end
    end
    result(i,j) = (accumulation_value);
end
result_blur_1 = uint8(255*mat2gray(result));

M = size(graymap,1);
N = size(graymap,2);

resIFFT = ifft2(fft2(double(graymap), M, N) .* fft2(double(z), M, N));
result_blur_2 = uint8(255*mat2gray(resIFFT));
err = immse(result_blur_1, result_blur_2);

z是9 * 9高斯核。我不翻转它,因为它是对称的。

我认为我的卷积实现是正确的,因为结果与conv2(graymap,z,'same')相同。

因此,我认为第二部分有问题。事实上,我对填充如何工作感到困惑。可能它是大型MSE的原因。

1 个答案:

答案 0 :(得分:1)

第二部分的实施确实存在问题。通过fft实现卷积时要记住的最重要的规则是,您实际上是在计算 圆形 卷积,而不是 线性 卷积。幸运的是,存在两种情况相同的条件。这个条件是两个数组应该是零填充的,其大小等于每个减去1 (在所有维度中)的大小之和。因此,如果您使用的是尺寸为X x M的图片N,以及尺寸为Z x P的图片Q,则你应该用零填充两个数组,以便 至少 M+P-1 x N+Q-1。任何额外的零都不会受到伤害,因此匹配友好的 &#39;尽可能的大小(例如使用nextpow2)。您只需要获取第一个M+P-1 x N+Q-1值。

现在,如果您只想要卷积的完整结果,这将直接进行。但是因为你想要卷积的中心部分(选项&#39;相同&#39;),你需要选择正确的索引。第一个索引将是ceil(([P Q] - 1)/2) + 1,然后您将获取与图像大小一样多的连续索引。

以下是将所有内容放在一起的示例:

M = randperm(1024,1);
N = randperm(1024,1);

X = rand(M,N);

P = randperm(64,1);
Q = randperm(64,1);

Z = rand(P,Q);

% 'standard' convolution with option 'same'
C1 = conv2(X,Z,'same');


R = 2^nextpow2(M+P-1);
S = 2^nextpow2(N+Q-1);

% convolution with fft. Notice the zero-padding to R,S
C2 = real(ifft2(fft2(X,R,S) .* fft2(Z,R,S)));

n       = ceil(([P Q] - 1)/2);
ind{1}  = n(1) + (1:M);
ind{2}  = n(2) + (1:N);

C2 = C2(ind{:});

err = immse(C1,C2)

我收到1e-26

的错误