使用FFTW进行图像卷积时,内核的中心位置是什么?

时间:2012-06-25 19:21:30

标签: image-processing fft fftw convolution

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

首先,为了测试系统是否正常工作,我执行了fft,然后是反向fft,并且可以获得返回的完全相同的图像。

然后向前迈出了一小步,我使用了标识内核(即kernel [0] [0] = 1,而所有其他组件都等于0)。我在图像和内核之间(都在频域中)采用了分量方面的产品,然后进行了反向fft。从理论上讲,我应该能够得到相同的图像。但我得到的结果甚至都不接近原始图像。我怀疑这与我将内核置于频域之前的内核有关(因为我将“1”置于内核[0] [0],它基本上意味着我将正面部分置于顶部剩下)。谁能告诉我这里出了什么问题?

3 个答案:

答案 0 :(得分:4)

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

E.g。 -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)。

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

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

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

在IFFT之后不要忘记 FFTSHIFT 。 (换掉象限。)
IFFT的结果是0 ... n-1。您必须采用像素层(n / 2)+ 1..n-1并在0 ... floor(n / 2)之前移动它们。
这是通过将像素复制到新图像,将楼层(n / 2)+1复制到存储器位置0,将楼层(n / 2)+2复制到存储器位置1,...,n-1到存储器来完成的。位置楼层(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。将结果与输入进行比较来判断)。

答案 1 :(得分:0)

我认为您对Identity内核的理解可能已经过时。一个Identity内核应该在2D内核的中心不是0,0位置。

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

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

应该是

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

同时检查

What is the "do-nothing" convolution kernel

另见第3页底部。

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

答案 2 :(得分:-1)

  

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

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