1. 程式人生 > >如何確定高斯濾波的標準差和視窗大小

如何確定高斯濾波的標準差和視窗大小

高斯函式與高斯濾波

一維高斯函式我們都熟悉,形式如下:

\[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個範圍在一維和二維高斯中示意如下:

Gaussian n sigma 範圍

OpenCV中標準差與視窗大小的換算

在OpenCV函式createGaussianFilter中,若未指定視窗大小,通過\(\sigma\)推算視窗大小方式如下,半徑為\(\sigma\)的3或4倍:

Gaussian kernel size

若指定了視窗大小,但未指定\(\sigma\)大小,則通過視窗大小推算\(\sigma\)的方式如下:

\[\sigma = 0.3\times((ksize - 1)\times0.5 - 1) + 0.8\]

具體地,在函式getGaussianKernel中,當ksize不大於7時,直接從內部的\(small_gaussian_tab\)取對應大小的高斯核,若大於7,則使用上式計算出\(\sigma\)然後套用高斯公式,最後再歸一化。

getGaussianKernel

在實際使用時,為了高效,卷積核通常取\([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。

參考