如何将两个不同尺寸图像的光谱相乘?

时间:2009-09-03 21:32:38

标签: image-processing signal-processing fft convolution

这不是一个“编程”问题。但我确信这是在这个社区中广为人知和理解的东西。

我有一个图像,x和一个小得多的图像y,我需要通过乘以它们来对两者进行卷积。但由于它们的大小不同,我不知道如何进行频域乘法。

我采用x的(二维)FFT(这是一个尺寸为4096 x 4096的整数矩阵),它给出了频域表示X(这是一个复数矩阵,我认为它的维数是2048 x 2048)。

类似地,我采用(二​​维FFT的y(这是一个64 x 64的整数矩阵),它给出了频域表示,Y(也是一个复数矩阵,我认为它是尺寸为32 x 32)。

我正在使用数字配方中的fourn函数,因此我的输入矩阵x和y必须折叠成一维数组,然后由它们的离散傅立叶变换X和Y代替。重点是即使这是图像的二维问题,我正在使用一维数组。

如果我试图卷积两个完全相同尺寸的图像,x和y。这一切都非常简单:

 X = FFT(x)

 Y = FFT(y)

 Z = X * Y (term by term multiplication)

 Convolution of x and y = IFFT(Z)

但如果X和Y的长度不同,我该如何进行乘法?

一种可能性是将y填充为具有与x相同的尺寸。但这似乎非常低效。另一种可能性是将Y填充为与X具有相同的尺寸。但我不知道这在频率空间中意味着什么。

这是提出这个问题的另一种方式:如果我想使用FFT对两个不同维度的图像进行卷积,那么我可以对它们的光谱进行乘法(频域表示),我该如何进行乘法?

谢谢,

〜迈克尔。

2 个答案:

答案 0 :(得分:6)

使用零填充较小的数组(卷积内核,在您的情况下为y)以匹配输入图像大小(矩阵x)是标准方法。如果你在空间域中进行卷积,那么将会非常低效,但是如果你将FFT相乘,那么它是必要的,并且计算填充数组的FFT的成本也不是很高坏。

答案 1 :(得分:4)

你认为两个频率间距必须相同是正确的。举一个例子(我使用的是Matlab语法):

N = 4096;
M = 64;

x = randn(N, 1);
y = hann(M, 'symmetric');

zLinear = conv(x,y);
zCircular = ifft( fft(x) .* fft(y,N) );

disp(max(abs(zLinear(65:4096) - zCircular(65:4096))));

两种技术之间的差异是~2e-14,因此舍入误差。请注意,由于线性和循环卷积之间的差异,您必须跳过前64个样本。

在zCircular的计算中,注意fft(y,N),这是Matlab语法,用于在计算fft之前用0填充y信号。这可能被认为在内存使用方面效率低下,但比较速度:

线性卷积:4096乘法/加64,每个= 262144乘/加

循环卷积:2个FFT,4096 + 1个复数乘法2 * 4096个元素+ 1个逆FFT  = 3 * 4096 * log2(4096)+ 4096 * 6 = 172032(假设复数乘法运算6次)

基本上,即使你需要其中三个,FFT的NlogN速度也会超过N * M卷积运算,除非M非常短。

编辑为2D案例添加速度估算

值得补充的是,对于2D数据,速度优势被放大了。 2D FFT采用N * N * log2(N * N)运算,因此对于N = 4096,3个FFT +复数N ^ 2阵列乘法是1.3e10运算。但直接卷积是N ^ 2 * M ^ 2 = 6.9e10操作,慢了约50倍。