一维高斯函数我们都熟悉,形式如下:
G ( x ) = 1 2 π σ exp ( − x 2 2 σ 2 ) G(x) = \frac{1}{\sqrt{2\pi}\sigma} \exp(-\frac{x^2}{2\sigma^2}) G(x)=2πσ1exp(−2σ2x2)
计算机视觉中,高斯滤波使用的高斯核为 x x x和 y y y两个一维高斯的乘积,两个维度上的标准差 σ \sigma σ通常相同,形式如下:
G ( x , y ) = 1 2 π σ 2 exp ( − x 2 + y 2 2 σ 2 ) G(x, y) = \frac{1}{2\pi\sigma^2}\exp(-\frac{x^2+y^2}{2\sigma^2}) G(x,y)=2πσ21exp(−2σ2x2+y2)
高斯滤波(平滑),即用某一尺寸的二维高斯核与图像进行卷积。高斯核是对连续高斯函数的离散近似,通常对高斯曲面进行离散采样和归一化得出,这里,归一化指的是卷积核所有元素之和为1,下图为标准高斯和 σ = 1.4 \sigma=1.4 σ=1.4大小为 5 × 5 5\times5 5×5的高斯核。
当 μ = 0 \mu=0 μ=0时,唯一需要控制的参数就是标准差 σ \sigma σ,多少合适呢? σ \sigma σ的确定十分依赖于问题背景,需要具体问题具体分析。但理解 σ \sigma σ的作用,可以指导调整的方向。
高斯核可以看成是与中心距离负相关的权重。平滑时,调整 σ \sigma σ实际是在调整周围像素对当前像素的影响程度,调大 σ \sigma σ即提高了远处像素对中心像素的影响程度,滤波结果也就越平滑。高斯曲线随 σ \sigma σ变化的曲线如下:
从频域角度看,高斯函数的傅立叶变换仍是高斯,两者标准差间的关系如下:
σ x = 1 2 π σ w \sigma_x = \frac{1}{2\pi \sigma_w} σx=2πσw1
其中, σ x \sigma_x σx为空域高斯的标准差, σ w \sigma_w σw为对应频域高斯的标准差,在空域进行高斯平滑相当于频域低通滤波, σ x \sigma_x σx越大, σ w \sigma_w σw越小,频域高斯越集中,高频成分削弱得越多,图像越平滑。
从低通滤波角度考虑,可以对图像做傅立叶变换进行频谱分析,叠加上频域高斯并调整查看效果,找到适合的 σ w \sigma_w σw,再推算出空域高斯所需的 σ x \sigma_x σx。
标准差 σ \sigma σ确定后,接下来需要确定窗口大小。上面讲了高斯核是对连续高斯的离散近似,窗口越大自然近似越好,但高斯函数是钟形曲线,距离中心越远数值越小,足够远处可以忽略不计,但多远算远呢?
钟型曲线在区间 ( μ − σ , μ + σ ) (\mu - \sigma, \mu +\sigma) (μ−σ,μ+σ)范围内的面积占曲线下总面积的 68 % 68\% 68%, ( μ − 2 σ , μ + 2 σ ) (\mu - 2\sigma, \mu +2\sigma) (μ−2σ,μ+2σ)范围占 95 % 95\% 95%, ( μ − 3 σ , μ + 3 σ ) (\mu - 3\sigma, \mu +3\sigma) (μ−3σ,μ+3σ)范围占 99.7 % 99.7\% 99.7%,一般 3 σ 3\sigma 3σ外的数值已接近于0,可忽略,半径为 3 σ 3\sigma 3σ即窗口大小为 6 σ × 6 σ 6\sigma \times 6\sigma 6σ×6σ即可,通常取最近的奇数。上述3个范围在一维和二维高斯中示意如下:
在OpenCV函数createGaussianFilter
中,若未指定窗口大小,通过 σ \sigma σ推算窗口大小方式如下,半径为 σ \sigma σ的3或4倍:
若指定了窗口大小,但未指定 σ \sigma σ大小,则通过窗口大小推算 σ \sigma σ的方式如下:
σ = 0.3 × ( ( k s i z e − 1 ) × 0.5 − 1 ) + 0.8 \sigma = 0.3\times((ksize - 1)\times0.5 - 1) + 0.8 σ=0.3×((ksize−1)×0.5−1)+0.8
具体地,在函数getGaussianKernel
中,当ksize
不大于7时,直接从内部的 s m a l l g a u s s i a n t a b small_gaussian_tab smallgaussiantab取对应大小的高斯核,若大于7,则使用上式计算出 σ \sigma σ然后套用高斯公式,最后再归一化。
在实际使用时,为了高效,卷积核通常取 [ 0 , 255 ] [0, 255] [0,255]范围内的整数(1个Byte),因此高斯核中心最大取值为255时,窗口尺寸的选取只需让高斯核边界值刚好大于0即可。令高斯核尺寸为 n n n,半径为 r r r, r = n − 1 2 r = \frac{n-1}{2} r=2n−1,高斯核 x x x轴上边界 ( r , 0 ) (r, 0) (r,0)处与中心 ( 0 , 0 ) (0, 0) (0,0)处数值之比如下:
G ( r , 0 ) G ( 0 , 0 ) = exp ( − r 2 2 × ( 0.3 ( r − 1 ) + 0.8 ) 2 ) \frac{G(r, 0)}{G(0, 0)} = \exp(-\frac{r^2}{2 \times (0.3(r-1)+0.8)^2}) G(0,0)G(r,0)=exp(−2×(0.3(r−1)+0.8)2r2)
当 r r r足够大,其极限为 exp ( − 1 2 × 0. 3 2 ) = 0.00386592 \exp(-\frac{1}{2\times0.3^2})=0.00386592 exp(−2×0.321)=0.00386592,若中心值为255,则边界值为 255 ∗ 0.00386592 = 0.9858096 ≈ 1 255*0.00386592=0.9858096 \approx 1 255∗0.00386592=0.9858096≈1,是合适的。但公式是如何设计出来的还不清楚,这里只是校验了其性质,sigh。
本文出自本人博客:如何确定高斯滤波的标准差和窗口大小