如何確定高斯濾波的標準差和視窗大小
高斯函式與高斯濾波
一維高斯函式我們都熟悉,形式如下:
\[G(x) = \frac{1}{\sqrt{2\pi}\sigma} \exp(-\frac{x^2}{2\sigma^2})\]
計算機視覺中,高斯濾波使用的高斯核為 \(x\) 和 \(y\) 兩個一維高斯的乘積,兩個維度上的標準差 \(\sigma\) 通常相同,形式如下:
\[G(x, y) = \frac{1}{2\pi\sigma^2}\exp(-\frac{x^2+y^2}{2\sigma^2})\]
高斯濾波(平滑),即用某一尺寸的二維高斯核與影象進行卷積。高斯核是對連續高斯函式的離散近似,通常對高斯曲面進行離散取樣和歸一化得出,這裡,歸一化指的是卷積核所有元素之和為1,下圖為標準高斯和 \(\sigma=1.4\) 大小為 \(5\times5\) 的高斯核。
標準差
當 \(\mu=0\) 時,唯一需要控制的引數就是標準差 \(\sigma\) ,多少合適呢? \(\sigma\) 的確定十分依賴於問題背景,需要具體問題具體分析。但理解 \(\sigma\) 的作用,可以指導調整的方向。
高斯核可以看成是與中心距離負相關的權重。平滑時,調整 \(\sigma\) 實際是在調整週圍畫素對當前畫素的影響程度, 調大 \(\sigma\) 即提高了遠處畫素對中心畫素的影響程度 ,濾波結果也就越平滑。高斯曲線隨 \(\sigma\) 變化的曲線如下:

從頻域角度看,高斯函式的傅立葉變換仍是高斯,兩者標準差間的關係如下:
\[\sigma_x = \frac{1}{2\pi \sigma_w}\]
其中, \(\sigma_x\) 為空域高斯的標準差, \(\sigma_w\) 為對應頻域高斯的標準差,在空域進行高斯平滑相當於頻域低通濾波, \(\sigma_x\) 越大, \(\sigma_w\) 越小,頻域高斯越集中,高頻成分削弱得越多,影象越平滑。
從低通濾波角度考慮,可以對影象做傅立葉變換進行頻譜分析,疊加上頻域高斯並調整檢視效果,找到適合的 \(\sigma_w\) ,再推算出空域高斯所需的 \(\sigma_x\) 。
視窗大小
標準差 \(\sigma\) 確定後,接下來需要確定視窗大小。上面講了高斯核是對連續高斯的離散近似,視窗越大自然近似越好,但高斯函式是鐘形曲線,距離中心越遠數值越小,足夠遠處可以忽略不計,但多遠算遠呢?
鍾型曲線在區間 \((\mu - \sigma, \mu +\sigma)\) 範圍內的面積佔曲線下總面積的 \(68\%\) , \((\mu - 2\sigma, \mu +2\sigma)\) 範圍佔 \(95\%\) , \((\mu - 3\sigma, \mu +3\sigma)\) 範圍佔 \(99.7\%\) ,一般 \(3\sigma\) 外的數值已接近於0,可忽略,半徑為 \(3\sigma\) 即視窗大小為 \(6\sigma \times 6\sigma\) 即可,通常取最近的奇數。上述3個範圍在一維和二維高斯中示意如下:
OpenCV中標準差與視窗大小的換算
在OpenCV函式 createGaussianFilter
中,若未指定視窗大小,通過 \(\sigma\) 推算視窗大小方式如下,半徑為 \(\sigma\) 的3或4倍:
若指定了視窗大小,但未指定 \(\sigma\) 大小,則通過視窗大小推算 \(\sigma\) 的方式如下:
\[\sigma = 0.3\times((ksize - 1)\times0.5 - 1) + 0.8\]
具體地,在函式 getGaussianKernel
中,當 ksize
不大於7時,直接從內部的 \(small_gaussian_tab\) 取對應大小的高斯核,若大於7,則使用上式計算出 \(\sigma\) 然後套用高斯公式,最後再歸一化。
在實際使用時,為了高效,卷積核通常取 \([0, 255]\) 範圍內的整數(1個Byte),因此高斯核中心最大取值為255時,視窗尺寸的選取只需讓高斯核邊界值剛好大於0即可。令高斯核尺寸為 \(n\) ,半徑為 \(r\) , \(r = \frac{n-1}{2}\) ,高斯核 \(x\) 軸上邊界 \((r, 0)\) 處與中心 \((0, 0)\) 處數值之比如下:
\[\frac{G(r, 0)}{G(0, 0)} = \exp(-\frac{r^2}{2 \times (0.3(r-1)+0.8)^2})\]
當 \(r\) 足夠大,其極限為 \(\exp(-\frac{1}{2\times0.3^2})=0.00386592\) ,若中心值為255,則邊界值為 \(255*0.00386592=0.9858096 \approx 1\) ,是合適的。但公式是如何設計出來的還不清楚,這裡只是校驗了其性質,sigh。
參考
- ofollow,noindex" target="_blank">getGaussianKernel
- Calculate the Gaussian filter's sigma using the kernel's size
- Gaussian blur
- Gaussian Blur - Standard Deviation, Radius and Kernel Size
- How to determine the window size of a Gaussian filter
- Optimal Gaussian filter radius
- Fast Almost-Gaussian Filtering