發展到現在這個平滑演算法的時候, 我已經完全不知道如何去命名這篇文章了, 只好羅列出一些關鍵字來方便搜尋了.
在之前我們提到過了均值濾波器, 就是說某像素的顏色, 由以其為中心的九宮格的像素平均值來決定. 在這個基礎上又發展成了帶權的平均濾波器, 這裡的高斯平滑或者說濾波器就是這樣一種帶權的平均濾波器. 那麼這些權重如何分布呢? 我們先來看幾個經典的模板例子:
嘗試了使用這些濾波器對我們原來的圖進行操作, 得到了這樣的一組結果:
原圖:
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:
/**<br />** method to remove noise from the corrupted image by gaussian filter value<br />* @param corrupted input grayscale binary array with corrupted info<br />* @param smooth output data for smooth result, the memory need to be allocated outside of the function<br />* @param width width of the input grayscale image<br />* @param height height of the input grayscale image<br />*/<br />void gaussianFilter2 (unsigned char* corrupted, unsigned char* smooth, int width, int height)<br />{<br />int templates[25] = { 1, 4, 7, 4, 1,<br /> 4, 16, 26, 16, 4,<br /> 7, 26, 41, 26, 7,<br /> 4, 16, 26, 16, 4,<br /> 1, 4, 7, 4, 1 };</p><p>memcpy ( smooth, corrupted, width*height*sizeof(unsigned char) );<br />for (int j=2;j<height-2;j++)<br />{<br />for (int i=2;i<width-2;i++)<br />{<br />int sum = 0;<br />int index = 0;<br />for ( int m=j-2; m<j+3; m++)<br />{<br />for (int n=i-2; n<i+3; n++)<br />{<br />sum += corrupted [ m*width + n] * templates[index++] ;<br />}<br />}<br />sum /= 273;<br />if (sum > 255)<br />sum = 255;<br />smooth [ j*width+i ] = sum;<br />}<br />}<br />}
附帶說一些,很明顯,和均值濾波器類似, 這個濾波器沒有消除校正雜訊的作用.