如何在频域中实现卷积?

use*_*312 3 fft image-processing c#-4.0

假设,我们有一个位图图像表示为2D整数数组, int [,] image2D;其FFT为Complex[,] fftImage2D;

假设,我们有一个表示为2D整数数组的内核, int [,] kernel2D;其FFT为Complex[,] fftKernel2D;

我们知道,卷积(在空间域中)image2Dkernel2D将来,

int Rows = image2D.GetLength(0);
int Cols = image2D.GetLength(1);

for(int i=0 ; i<Rows ; i++)
{
    for(int j=0 ; j<Cols ; j++)
    {
        //sweep the kernel2D across image2D
        //...........................
    }
}
Run Code Online (Sandbox Code Playgroud)

以下链接都是关于空间域中的卷积:

http://www.codeproject.com/Articles/2008/Image-Processing-for-Dummies-with-C-and-GDI-Part http://www.gutgames.com/post/Matrix-Convolution-Filters-in -C.aspx https://softwarebydefault.com/2013/05/01/image-convolution-filters/

频域中的卷积将在fftImage2D和之间相乘fftKernel2D.

我该怎么做这个乘法?

如何将两个Complex [,]不同尺寸的2D阵列相乘?

Sle*_*Eye 5

要通过在频域中使用乘法来执行线性卷积,必须首先确保两个复杂的2D阵列具有相同的尺寸.这可以通过将两个空间域阵列(image2Dkernel2D)填充到相同的大小来实现.请注意,您必须将空间域数组填充到至少比两个数组维度(沿每个维度)的总和少一个,以执行线性卷积而不是循环卷积.

所以过程看起来像:

  • 计算填充行数: image2D.GetLength(0)+kernel2D.GetLength(0)-1
  • 计算填充列数: image2D.GetLength(1)+kernel2D.GetLength(1)-1
  • 填充image2D此新大小,重复边框元素
  • 填充kernel2D这个新的大小,填入零
  • 计算填充image2D和FFT的FFTkernel2D
  • 执行补齐乘法fftImage2DfftKernel2D现在是一样大小的
  • 计算逆FFT
  • (可选)将结果截断为原始image2D大小(仅当您对获取由kernel2D没有完整卷积带来的边缘效果而过滤的图像感兴趣时才需要此选项).

对于示例实现,未来的读者可能会看看@anonymous中的另一个问题以及我在答案中指出的更改.