高斯函數與高斯濾波
一維高斯函數我們都熟悉,形式如下:
計算機視覺中,高斯濾波使用的高斯核為\(x\)和\(y\)兩個一維高斯的乘積,兩個維度上的標准差\(\sigma\)通常相同,形式如下:
高斯濾波(平滑),即用某一尺寸的二維高斯核與圖像進行卷積。高斯核是對連續高斯函數的離散近似,通常對高斯曲面進行離散采樣和歸一化得出,這里,歸一化指的是卷積核所有元素之和為1,下圖為標准高斯和\(\sigma=1.4\)大小為\(5\times5\)的高斯核。
標准差
當\(\mu=0\)時,唯一需要控制的參數就是標准差\(\sigma\),多少合適呢?\(\sigma\)的確定十分依賴於問題背景,需要具體問題具體分析。但理解\(\sigma\)的作用,可以指導調整的方向。
高斯核可以看成是與中心距離負相關的權重。平滑時,調整\(\sigma\)實際是在調整周圍像素對當前像素的影響程度,調大\(\sigma\)即提高了遠處像素對中心像素的影響程度,濾波結果也就越平滑。高斯曲線隨\(\sigma\)變化的曲線如下:
從頻域角度看,高斯函數的傅立葉變換仍是高斯,兩者標准差間的關系如下:
其中,\(\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\)的方式如下:
具體地,在函數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)\)處數值之比如下:
當\(r\)足夠大,其極限為\(\exp(-\frac{1}{2\times0.3^2})=0.00386592\),若中心值為255,則邊界值為\(255*0.00386592=0.9858096 \approx 1\),是合適的。但公式是如何設計出來的還不清楚,這里只是校驗了其性質,sigh。
參考
- 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
- Gaussian Smoothing
本文出自本人博客:如何確定高斯濾波的標准差和窗口大小