6

我正在尝试使用 FFTW 进行图像卷积。

起初只是为了测试系统是否正常工作,我执行了 fft,然后执行了逆 fft,并且可以得到完全相同的图像返回。

然后向前迈出一小步,我使用了身份内核(即,内核[0][0] = 1,而所有其他组件都等于 0)。我在图像和内核(都在频域中)之间取了分量乘积,然后做了逆 fft。从理论上讲,我应该能够得到相同的图像。但是我得到的结果与原始图像非常不一样。我怀疑这与我在将内核 fft 进入频域之前将内核居中的位置有关(因为我将“1”放在内核 [0] [0] 中,这基本上意味着我将积极的部分居中在顶部剩下)。谁能告诉我这里出了什么问题?

4

3 回答 3

3

对于每个维度,样本的索引应该从 -n/2 ... 0 ... n/2 -1,所以如果维度是奇数,则以中间为中心。如果维度是偶数,则居中,以便在新 0 之前比在新 0 之后多一个样本。

例如 -4, -3, -2, -1, 0, 1, 2, 3 用于宽度/高度 8 或 -3, -2, -1, 0, 1, 2, 3 用于宽度/高度7.

FFT 是相对于中间的,在它的尺度上有负点。
在内存中,点是 0...n-1,但 FFT 将它们视为 -ceil(n/2)...floor(n/2),其中 0 是 -ceil(n/2) 和 n- 1 是地板(n/2)

单位矩阵是一个零矩阵,在 0,0 位置(中心 - 根据上述编号)为 1。(在空间域中。)

在频域中,单位矩阵应该是一个常数(所有实数值为 1 或 1/(N*M),所有虚数值为 0)。

如果您没有收到此结果,则识别矩阵可能需要不同的填充(向左和向下而不是围绕所有边) - 这可能取决于 FFT 实现。

分别居中每个维度(这是一个索引居中,实际内存没有变化)。

您可能需要在每个维度上将图像(居中后)填充为 2 的整数幂(2^n * 2^m,其中 n 不必等于 m)。

通过在源图像和目标图像中使用基于中心的索引(例如 (0,0) 到 (0,0))将现有像素复制到新的更大图像中,相对于 FFT 的 0,0 位置(到中心,而不是角落)进行填充, (0,1) 到 (0,1), (1,-2) 到 (1,-2))

假设您的 FFT 使用常规浮点单元而不是复杂单元,即使您不需要 2 的整数幂,复杂图像的大小也必须为 2*ceil(2/n) * 2*ceil(2/m) (因为它有一半的样本,但样本很复杂)。

如果您的图像有多个颜色通道,则首先必须对其进行整形,以便通道在子像素排序中是最重要的,而不是最不重要的。您可以一次性重塑和填充,以节省时间和空间。

不要忘记IFFT之后的FFTSHIFT。(交换象限。)
IFFT 的结果是 0...n-1。您必须取像素 floor(n/2)+1..n-1 并将它们移动到 0...floor(n/2) 之前。
这是通过将像素复制到新图像、将 floor(n/2)+1 复制到内存位置 0、将 floor(n/2)+2 复制到内存位置 1、...、n-1 到内存位置来完成的location floor(n/2), 然后 0 到内存位置 ceil(n/2), 1 到内存位置 ceil(n/2)+1, ..., floor(n/2) 到内存位置 n -1。

当您在频域中相乘时,请记住样本是复数(一个实数单元,然后一个虚数单元),因此您必须使用复数乘法。

结果可能需要除以 N^2*M^2,其中 N 是填充后 n 的大小(对于 M 和 m 也是如此)。- 您可以通过(a.查看单位矩阵的频域值,b.将结果与输入进行比较。)

于 2012-06-25T20:17:40.580 回答
0

我认为您对身份内核的理解可能不正确。一个身份内核应该在 2D 内核的中心有 1,而不是在 0、0 位置。

例如 3 x 3,您的设置如下:

1, 0, 0
0, 0, 0
0, 0, 0

它应该是

0, 0, 0
0, 1, 0
0, 0, 0

也检查一下

什么是“无所事事”的卷积核

也看这里,在第 3 页的底部。

http://www.fmwconcepts.com/imagemagick/digital_image_filtering.pdf

于 2012-06-25T19:26:30.967 回答
-1

我在频域中取图像和内核之间的分量乘积,然后进行逆 fft。从理论上讲,我应该能够得到相同的图像。

我不认为使用非 fft 内核进行正向变换,然后进行反向 fft 变换应该会导致任何期望恢复原始图像,但也许我只是误解了你在那里想说的话。 ..

于 2012-06-25T19:49:56.987 回答