我正在为一个类编写一个c ++程序来在频域中进行卷积,我注意到最终结果出现了错误。所以我在MATLAB中尝试了它并得到了完全相同的结果。 e.g。
使用http://engronline.ee.memphis.edu/eece7214/images/Downlodable.htm
中的摄影师我做了
a = imread('cameraman.pgm');
h = ones(25,25)/25/25;
a(512,512) = 0;
h(512,512) = 0;
c = ifft2(fft2(a).*fft2(h))/256;
c = c(1:256, 1:256);
c = real(c);
imwrite(c,'test2.png')
我在提取左上角之前偷看了c,我发现它与imfilter(a,h)的答案相同,只不过它从角落翻了一下。 Gonzalez的数字图像处理没有说明这一点,谷歌在没有任何帮助的情况下让我的眼睛流下了搜身(每个人都重复了Gonzalez提取左上角的相同指示)。
与主要问题无关,我也想知道为什么我必须在这个MATLAB代码中除以256。在我的C ++代码中,我没有必要扩展结果,我得到了与这个MATLAB代码相同的答案。
编辑: 我做了一点玩一维矢量(做转换和ifft(fft * fft)),我认为'错误'来自输出显示左上角的'完整'卷积而不是'相同' '卷积。但即使是这种情况,我也不确定如何确定性地编码“仅提取此部分以获得'相同'而不是'完整'的左上角256x256部分”
编辑: 更多谷歌搜索通过http://jeremy.fix.free.fr/IMG/pdf/fftconvolution.pdf导致了可能的解决方案。它有很多我以前从未见过的数学符号,但是从我可以收集的内容来看,如果你正在卷积一个nxn和一个mxm,则提取m:(m + n-1)以得到来自它的'相同'卷积fft近似。我仍然希望听到一位比我更专业的人,所以不要选择不根据此更新发表评论!
答案 0 :(得分:2)
MATLAB将数组从1索引到N.
Canonical C用法(和大多数C矩阵数学库)索引从0到N-1的数组。
这可能是一个逐个差异的来源。
要成为一个身份,裸ifft(fft(x))算法需要在某处使用1 / N的比例因子。 一些C库将1 / N放在fft()中。许多人将这个比例因子构建到ifft()中。有些人在两者中都加1 / sqrt(N)。有些没有添加内置的比例因子,需要用户根据需要进行扩展以获得身份。
答案 1 :(得分:0)
您需要将其移动窗口大小的一半。 在这种情况下,你应该这样做: c = c(13:256 + 12,13:256 + 12); 代替: c = c(1:256,1:256);
你用零填充信号,但没有使用它,因为你从1到256信号 - 你仍然有边缘的捶打和你失去的右角的有价值的信号。