どんなガウシアンぼかし画像を使用せずに構築ガウス性能におい
-
18-09-2019 - |
質問
したいぼかし私のイメージ用のネイティブガウスぼかし式です。を読み込みま Wikipediaの記事, が、私にはどのように実施します。
の使い方を教えてください式の決定ウエイト?
私は利用しない為内蔵機能のようなMATLABは
解決
素朴なガウスぼかしを書くことは実際にはかなり簡単です。これは、他の畳み込みフィルタと全く同じ方法で行われます。ボックスとガウスフィルタの唯一の違いは、使用する行列である。
あなたは次のように定義されたイメージを持っている想像します:
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
次のようにの3x3ボックスフィルタ行列が定義されている
0.111 0.111 0.111
0.111 0.111 0.111
0.111 0.111 0.111
あなたが次のことを行うだろうガウスぼかしを適用するには
画素11のためには画素0、1、2、10、11、12、20、21、22をロードする必要がある。
これで、3×3のぼかしフィルタの左上部に画素0を掛けることになります。ように中央左とによって上部中央、画素2、右上によって画素3、画素10によって画素1。
次に、完全にそれらを追加し、画素11は、現在自身の平均値と周囲画素で見ることができるように、画素11に結果を書き込む。
エッジの場合は、もう少し複雑になりません。あなたは、テクスチャのエッジの値に対してどのような値を使用していますか?一つの方法は、他の側にラウンドラップすることができます。これは、後にタイル張りされた画像のためによさそうです。別の方法は、周囲の場所にピクセルをプッシュすることである。
次のようにサンプルを置くかもしれない左上のためだからます:
0 0 1
0 0 1
10 10 11
私はあなたが、これは簡単に大きなフィルタカーネル(つまり、5×5または9×9など)に拡張することができる方法を見ることができると思います。
ガウスフィルタとボックスフィルタの違いは、マトリックスに行くの数字です。ガウシアンフィルタは、行と列の両端のガウス分布を使用します。
例えば
(つまり、これはガウスではありませんが、おそらくそう遠くないオフ)として任意に定義されたフィルタのための0.1 0.8 0.1
最初の列は同じであるが、上記の行の最初の項目に乗じることになる。
0.01 0.8 0.1
0.08
0.01
2番目の列は同じであるが、値が上の行に0.8を乗じた(など)であろう。
0.01 0.08 0.01
0.08 0.64 0.08
0.01 0.08 0.01
一緒に上記の全てを加算した結果が1に等しくなければならない上記フィルタと元のボックスフィルタの差が書き込ま終了画素が中心画素(すなわち、あるものに向かってはるかに重い重みを有することであろうすでにその位置にあります)。周囲の画素はいえない限り、その画素にぼけないためぼやけが生じます。フィルタのこの種を使用して、あなたがブラーが、高い周波数の限りを破壊しない1(ピクセルからピクセルへの色の変化、すなわち迅速な)情報を取得します。
フィルタのこれらのソート順は面白いものの多くを行うことができます。もしエッジを行うことができ、現在の画素から周辺画素を減算することにより、フィルタのこの種を使用して検出します。これは、背後にある色(高周波数)でのみ本当に大きな変化を残すだろう。
編集:5x5のフィルタカーネルが正確に上記のように定義している
。例えば、列を形成し、その後に終わるだろうにこれ第二のカラムを形成するために、2番目の項目によってそれぞれを乗算し、第1の項目によって、それらの各値を乗算した場合、あなたの行は、その後0.1 0.2 0.4 0.2 0.1である場合
のフィルター付き0.01 0.02 0.04 0.02 0.01
0.02 0.04 0.08 0.04 0.02
0.04 0.08 0.16 0.08 0.04
0.02 0.04 0.08 0.04 0.02
0.01 0.02 0.04 0.02 0.01
0が0.1 * 0.1シンプルで、あなたはその位置0を見ることができ、いくつかの任意の位置を取ります。位置0、2 2が0.2×0.4であり、2は0.4×0.4及び位置1で、0.1×0.4、2位である。
私はあなたに十分な説明を与える願っています。
他のヒント
ここで私は、カーネルを計算するためにC#で使用されるコードのための擬似コードです。でも、私は私が正しく終了状態を治療することをあえて言うはありません。
double[] kernel = new double[radius * 2 + 1];
double twoRadiusSquaredRecip = 1.0 / (2.0 * radius * radius);
double sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(2.0 * Math.PI) * radius);
double radiusModifier = 1.0;
int r = -radius;
for (int i = 0; i < kernel.Length; i++)
{
double x = r * radiusModifier;
x *= x;
kernel[i] =
sqrtTwoPiTimesRadiusRecip * Exp(-x * sqrtTwoPiTimesRadiusRecip);
r++;
}
double div = Sum(kernel);
for (int i = 0; i < kernel.Length; i++)
{
kernel[i] /= div;
}
これが役立つことを願っています。
あなたは(離散)畳み込みを実装する必要がWikipediaの記事で説明したフィルタカーネルを使用するにする 。考え方は、値の小さなマトリックス(カーネル)、あなたが画像の画素に画素から、このカーネルを移動していることである(行列の中心画素になるように、すなわち)、重複画像との行列要素を乗算要素は、結果のすべての値を合計し、この合計で古いピクセル値を置き換えます。
ガウスぼかしではなく、ビットを物事をスピードアップ2D畳み込み、2つの一次元畳み込み(一垂直及び水平もの)に分離することができる。
私はあなたがこれを制限するかどうかは明らかではないのです。からの特定の技術、そうでない場合、<のhref =「http://www.w3.org/Graphics/SVG/」のrel =」ガウスぼかしの実装を持っているのnoreferrer nofollowを "> SVG(ScalableVectorGraphics)。私はそれが画素を含むすべてのプリミティブに適用されると信じています。 SVGは、オープンスタンダードであると広く実装の利点を有する。
でもガウスカーネルで分離を含んでいます。
そのため会員になるために必要な機能を支える分離型2次元のように畳み込み- ImageConvolutionSeparableKernel()
.
まで、すべての必要なのは、ラッパーを1次元ガウスカーネルに送って機能で ImageConvolutionGaussianKernel()
.
このコードは、前述のC実装は2次元画像の畳み込みにより加速されSIMD(SSE)およびマルチスレッド(OpenMP).
全体のプロジェクトで与えられます- 画像の畳み込み-GitHub.