1

私はいくつかのビデオ処理を行っています。フレームごとに、二変量関数の勾配を取得する必要があります。関数は double の 2 次元配列として表されます。ドメインは行と列のインデックスで、範囲は対応するインデックス値の double 値です。またはもっと簡単に言えば、関数は次のようfに定義されています。double[][] matrix

f(x,y)=matrix[x][y]

私はそれに Apache Commons Math ライブラリを使用しようとしています:

SmoothingPolynomialBicubicSplineInterpolator iterpolator = new SmoothingPolynomialBicubicSplineInterpolator();
BicubicSplineInterpolatingFunction f = iterpolator.interpolate(xs, ys, matrix.getData());
    for (int i = 0; i < ans.length; i++) {
        for (int j = 0; j < ans[0].length; j++) {
            ans[i][j] = f.partialDerivativeY(i, j); 
        }
    }
  • x インデックスのソートされた配列として xs を使用(0,1,...,matrix.getRowDimension() - 1)
  • はい、列の次元で同じです(0,1,...,matrix.getColumnDimension() - 1)

問題は、そのサイズの典型的なマトリックスの場合、実行に数秒150X80かかる1.4ため、私のニーズにはまったく関係がないことです。したがって、このライブラリの初心者ユーザーとして、またプログラムによる数値解析一般として、次のことを知りたいと思います。

  1. 私は何か間違ったことをしていますか?
  2. このタスクを達成できる別のより高速な方法はありますか?
  3. 解決策を提供する別のオープン ソース ライブラリ (できれば maven に適したもの) はありますか?
4

1 に答える 1

0

数値微分はそれ自体が全体のトピックであり、単純な Google で作業するのに十分な資料が表示されるはずです (wiki だけで十分かもしれません)。私が知ることができない問題のパラメーターがあるため、ここでは大まかにしか話せませんが、特定の点で勾配を決定する直接的な方法、つまり補間を必要としない方法があります。式については、ウィキペディアを参照してください (単純なf(x+1)-f(x)、つまり whereh=1から高次のものまで)。偏導関数の計算は、非常に簡単O(NM)な式を内部に持つ単純なループです (補間は必要ありません)。

詳細はざらざらしている可能性があります。

  1. 高次の式は、エッジに対して削減するか、完全に破棄する必要があります。
  2. 正確な速度要件により、より複雑な数式が役に立たなくなる可能性があります (プラットフォームによっては、高次の数式の検索時間が遅すぎる場合があります。これもキャッシュなどに依存します)。これは簡単にテストでき、式は単純です。それらをコーディングしてベンチマークします。
  3. 特定の実装は、エラー要件にも依存します。理論は誤差の範囲を提供するため、必要な式に影響を与えます。ただし、ここでも速度要件とのトレードオフがあります。処理する行列の種類についての詳細がわかっている場合は、実質的に下げることができます。

既存の畳み込みツールがある場合、この方法は実際には行列の畳み込みに過ぎないため、実装はさらに簡単 (そしておそらく高速) にすることができます (注意: 技術的には相互相関と呼ばれます)。

于 2013-01-19T16:57:04.940 に答える