代码之家  ›  专栏  ›  技术社区  ›  snakile

基于DSP的快速二维卷积

  •  7
  • snakile  · 技术社区  · 14 年前

    我想实现一些图像处理算法,这些算法打算在 beagleboard . 这些算法广泛使用卷积。我试图找到一个很好的二维卷积的C实现(可能使用快速傅立叶变换)。我还希望算法能够在beagleboard的DSP上运行,因为我听说DSP是为这些操作(使用其乘法累加指令)而优化的。

    我没有这个领域的背景,所以我认为自己实现卷积并不是一个好主意(我可能不会像一个了解卷积背后所有数学知识的人那样做得好)。我相信在某个地方有一个很好的C卷积实现,但我找不到它?

    有人能帮忙吗?

    编辑: 原来内核很小。它的尺寸是2X2或3X3。所以我想我不是在寻找基于FFT的实现。我在网上搜索卷积来查看它的定义,这样我就可以直接实现它(我不知道什么是卷积)。我只发现了一些乘法积分,我不知道如何处理矩阵。有人能给我一段2X2内核的代码(或伪代码)吗?

    2 回复  |  直到 14 年前
        1
  •  12
  •   Paul R    14 年前

    图像和内核的维数是多少?如果内核很大,那么可以使用基于FFT的卷积,否则对于小内核只使用直接卷积。

    对于小内核,可以执行如下直接卷积:

    // in, out are m x n images (integer data)
    // K is the kernel size (KxK) - currently needs to be an odd number, e.g. 3
    // coeffs[K][K] is a 2D array of integer coefficients
    // scale is a scaling factor to normalise the filter gain
    
    for (i = K / 2; i < m - K / 2; ++i) // iterate through image
    {
      for (j = K / 2; j < n - K / 2; ++j)
      {
        int sum = 0; // sum will be the sum of input data * coeff terms
    
        for (ii = - K / 2; ii <= K / 2; ++ii) // iterate over kernel
        {
          for (jj = - K / 2; jj <= K / 2; ++jj)
          {
            int data = in[i + ii][j +jj];
            int coeff = coeffs[ii + K / 2][jj + K / 2];
    
            sum += data * coeff;
          }
        }
        out[i][j] = sum / scale; // scale sum of convolution products and store in output
      }
    }
    

    您可以修改它以支持K的偶数值-只需稍微注意两个内部循环的上限/下限。

        2
  •  0
  •   Renato Gama    11 年前

    我知道这可能不是什么话题,但是由于C和JavaScript之间的相似性,我相信它仍然会有帮助。附言:灵感来自@Paul R answer。

    function newArray(size){
        var result = new Array(size);
        for (var i = 0; i < size; i++) {
            result[i] = new Array(size);
        }
    
        return result;
    }
    
    function convolveArrays(filter, image){
        var result = newArray(image.length - filter.length + 1);
    
        for (var i = 0; i < image.length; i++) {
            var imageRow = image[i];
            for (var j = 0; j <= imageRow.length; j++) {
    
                var sum = 0;
                for (var w = 0; w < filter.length; w++) {
                    if(image.length - i < filter.length) break;
    
                    var filterRow = filter[w];
                    for (var z = 0; z < filter.length; z++) {
                        if(imageRow.length - j < filterRow.length) break;
                        sum += image[w + i][z + j] * filter[w][z];
                    }
                }
    
                if(i < result.length && j < result.length)
                    result[i][j] = sum;
            }   
        }
    
        return result;
    }
    

    你可以在 http://ec2-54-232-84-48.sa-east-1.compute.amazonaws.com/two-dimensional-convolution-algorithm-with-arrays-in-javascript/