8

ビーグルボードで実行することを目的とした画像処理アルゴリズムを実装したいと考えています。これらのアルゴリズムは、畳み込みを広範囲に使用します。2D 畳み込み (おそらく高速フーリエ変換を使用) の適切な C 実装を見つけようとしています。また、ビーグルボードの DSP でアルゴリズムを実行できるようにしたいと考えています。なぜなら、DSP はこれらの種類の演算 (積和命令を使用) に最適化されていると聞いたからです。

私はこの分野のバックグラウンドを持っていないので、畳み込みを自分で実装するのは良い考えではないと思います (おそらく、その背後にあるすべての数学を理解している人ほどうまく実装できないでしょう)。DSP の優れた C 畳み込み実装がどこかにあると思いますが、見つけることができませんでしたか?

誰か助けてくれませんか?

編集:カーネルはかなり小さいことがわかりました。寸法は 2X2 または 3X3 です。だから私はFFTベースの実装を探していないと思います。Webで畳み込みを検索してその定義を確認していたので、簡単な方法で実装できます(畳み込みが何であるかはよくわかりません)。私が見つけたのは、積分を乗算したものだけで、行列でそれを行う方法がわかりません。誰かが 2X2 カーネルの場合のコード (または疑似コード) を教えてくれませんか?

4

2 に答える 2

15

画像とカーネルの寸法は? カーネルが大きい場合は、FFT ベースの畳み込みを使用できます。それ以外の場合は、小さなカーネルの場合は直接畳み込みを使用します。

ただし、DSP はこれを行うための最良の方法ではない可能性があります。MAC 命令があるからといって、より効率的であるとは限りません。Beagle Board の ARM CPU には NEON SIMD がありますか? もしそうなら、それは行くべき道かもしれません(そしてもっと楽しいです).

小さなカーネルの場合、次のように直接畳み込みを行うことができます。

// 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 つの内側のループの上限/下限に少し注意するだけです。

于 2010-10-20T21:42:48.213 に答える
1

話題から外れているかもしれませんが、CとJavaScriptが類似しているため、それでも役立つと思います。PS:@PaulRの回答に触発されました。

配列を使用したJavaScriptの2次元2D畳み込みアルゴリズム

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-dimension-convolution-algorithm-with-arrays-in-javascript/で確認できます。

于 2013-03-19T22:09:00.757 に答える