如何在频域中实现卷积?

时间:2016-06-12 21:41:24

标签: c#-4.0 image-processing fft

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

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

我们知道,kernel2Dint 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 //........................... } } 的卷积(在空间域中)将是,

fftImage2D

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

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/

频域中的卷积将在fftKernel2DComplex [,]之间相乘。

如何进行这种乘法?

如何将两个不同尺寸的$routeParams类型2D数组相乘?

2 个答案:

答案 0 :(得分:5)

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

所以过程如下:

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

对于示例实现,未来的读者可能会看到this other question from @anonymous以及我在my answer中指出的更改。

答案 1 :(得分:-1)

您必须使用multiplication of two complex numbers

这是一个用于两个1D数组的小java代码,具有这样的编码:[R1,C1,R2,C2,...,Rn,Cn]:

public void Multiply(double[] object1, double[] object2, double[] result)
{
double img_r, img_i, mask_r, mask_i ;

for (int pos=0 ; pos < result.length ; pos+=2)
    {
    img_r = object1[pos] ;
    img_i = object1[pos+1] ;

    mask_r = object2[pos] ;
    mask_i = object2[pos+1] ;

    result[pos]   = img_r*mask_r - img_i*mask_i;
    result[pos+1] = img_r*mask_i + img_i*mask_r ;
    }
}