このフィルタリングの問題には、よく知られた最適化があります。
- 細胞を一方向に統合する(水平方向など)
- 細胞を反対方向に統合する(垂直方向と言う)
- 各セルとその左隣の N 番目のセルとの差をとります。
- 各セルとその N 番目に低い隣接セルとの差を取る
このような:
for (i = 0; i < h; ++i)
for (j = 0; j < w-1; ++j)
A[i][j+1] += A[i][j];
for (i = 0; i < h-1; ++i)
(j = 0; j < w; ++j) の場合
A[i+1][j] += A[i][j]
for (i = 0; i < h; ++i)
for (j = 0; j < wN; ++j)
A[i][j] -= A[i][j+N];
for (i = 0; i < hN; ++i)
(j = 0; j < w; ++j) の場合
A[i][j] -= A[iN][j];
これが行うことは次のとおりです。
- 最初のパスは、各セルを、その行の左側にあるすべてのセル (それ自体を含む) の合計にします。
- 2 回目のパスの後、各セルは、セルの上下にある四角形内のすべてのセルの合計です (それ自体の行と列を含む)。
- 3 回目のパスの後、各セルは、それ自体の右上にある N 列幅の長方形の合計になります。
- 4 番目のパスの後、各セルは、それ自体の下と右にある NxN の四角形の合計になります。
これは、合計を計算するためにセルごとに 4 つの操作が必要ですが、ブルート フォースの場合は 8 回です (3x3 平均化フィルターを実行していると仮定します)。
優れた点は、通常の 2 の補数演算を使用する場合、最初の 2 つのパスでのオーバーフローを心配する必要がないことです。それらは最後の 2 つのパスで相殺されます。