以另外一個濾波器而言----均值濾波器, 就是說某像素的顏色, 由以其為中心的九宮格的像素平均值來決定. 在這個基礎上又發展成了帶權的“平均”濾波器, 這里的高斯平滑或者說濾波器就是這樣一種帶權(通常我們認為距離要代替的點像素的作用大一些)的“平均”濾波器. 那么這些權重如何分布呢? 我們先來看幾個經典的模板例子:


嘗試了使用這些濾波器對我們原來的圖進行操作, 得到了這樣的一組結果:
原圖:

3x3 高斯濾波處理后:

5x5 高斯處理后:

?
單純從效果來看, 兩個模板都起到了平滑的作用, 只是程度有深淺的區分. 那么從理論上來說為什么能起到平滑的作用呢? 很顯然, 像素的顏色不僅由自身決定了, 同時有其周圍的像素加權決定, 客觀上減小了和周圍像素的差異.同時這些權重的設定滿足了越近權重越大的規律. 從理論來講, 這些權重的分布滿足了著名的所謂高斯分布:
這就是1維的計算公式:

? ?
這就是2維的計算公式:

?
x, y表示的就是當前點到對應點的距離, 而那些具體的模板就是由這里公式中的一些特例計算而來. 需要說明的是不只有這么一些特例, 從wikipedia可以方便地找到那些復雜的模板比如像:
### Sample Gaussian matrix
This is a sample matrix, produced by sampling the Gaussian filter kernel (with σ = 0.84089642) at the midpoints of each pixel and then normalising. Note that the center element (at [4, 4]) has the largest value, decreasing symmetrically as distance from the center increases.
| 0.00000067 | 0.00002292 | **0.00019117** | 0.00038771 | **0.00019117** | 0.00002292 | 0.00000067 |
|-----|-----|-----|-----|-----|-----|-----|
| 0.00002292 | 0.00078633 | 0.00655965 | 0.01330373 | 0.00655965 | 0.00078633 | 0.00002292 |
| **0.00019117** | 0.00655965 | 0.05472157 | 0.11098164 | 0.05472157 | 0.00655965 | **0.00019117** |
| 0.00038771 | 0.01330373 | 0.11098164 | **0.22508352** | 0.11098164 | 0.01330373 | 0.00038771 |
| **0.00019117** | 0.00655965 | 0.05472157 | 0.11098164 | 0.05472157 | 0.00655965 | **0.00019117** |
| 0.00002292 | 0.00078633 | 0.00655965 | 0.01330373 | 0.00655965 | 0.00078633 | 0.00002292 |
| 0.00000067 | 0.00002292 | **0.00019117** | 0.00038771 | **0.00019117** | 0.00002292 | 0.00000067 |
是不是看到就頭大了?不過沒關系, 對于一般的應用來說, 前面的例子已經可以完成任務了.? 代碼的話我們還是給一份5x5的example:
~~~
<span style="font-size:12px;">void gaussianFilter2 (unsigned char* corrupted, unsigned char* smooth, int width, int height)
{
int templates[25] = { 1, 4, 7, 4, 1,
4, 16, 26, 16, 4,
7, 26, 41, 26, 7,
4, 16, 26, 16, 4,
1, 4, 7, 4, 1 }; //濾波器模板
memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) ); //復制像素
for (int j=2;j<height-2;j++) //邊緣不處理
{
for (int i=2;i<width-2;i++)
{
int sum = 0;
int index = 0;
for ( int m=j-2; m<j+3; m++)
{
for (int n=i-2; n<i+3; n++)
{
sum += corrupted [ m*width + n] * templates[index++] ;
}
}
sum /= 273;
if (sum > 255)
sum = 255;
smooth [ j*width+i ] = sum;
}
}
} </span>
~~~
參考資源:
【1】http://blog.csdn.net/hhygcy/article/details/4329056