I find on the OpenCV documentation for cvSmooth that sigma can be calculated from the kernel size as follows: sigma = 0.3(n/2 - 1) + 0.8
I would like to know the theoretical background of this equation.
Thank you.
I find on the OpenCV documentation for cvSmooth that sigma can be calculated from the kernel size as follows: sigma = 0.3(n/2 - 1) + 0.8
I would like to know the theoretical background of this equation.
Thank you.
Using such a value for sigma, the ratio between the value at the centre of the kernel and on the edge of the kernel, found for y=0 and x=n/2-1, is:
g_edge / g_center = exp(-(x²+y²)/(2σ²))
= exp(-(n/2-1)²/(2*(0.3(n/2-1)+0.8)²))
The limit of this value as n increases is:
exp(-1/(2*0.3²)) = 0.00386592
Note that 1/256 is 0.00390625. Images are often encoded in 256-value ranges. The choice of 0.3 ensures that the kernel considers all pixels that may significantly influence the resulting value.
I am afraid I do not have an explanation for the 0.8 part, but I imagine it is here to ensure reasonable values when n is small.
g_edge / g_center, as it appears on both sides of the division.We can see if the radius is big enough, it is actually 0.3r, match the sigma assumption: we need the filter radius to be 3sigma
the radius is (ksize-1)/2, thus in another words we need sigma = (ksize-1)/6. which is roughly 0.15*(ksize-1).
However, why we need the +0.5 ?
It is very simple. If we make the edge to be 0 for the small kernels, then only the centre has relatively big value. It becomes a per pixel scaling instead of filtering. For radius of 2, It looks like a triangle filter instead of gaussian
Thus we need an offset to make sure the small filter do have low pass effect.

size=3 : tensor([0.0109, 0.9783, 0.0109])
size=3 with +0.5 offset: tensor([0.2466, 0.5067, 0.2466])
size=5 : tensor([0.0066, 0.1942, 0.5983, 0.1942, 0.0066])
size=5 with +0.5 offset: tensor([0.0809, 0.2434, 0.3515, 0.2434, 0.0809])
size=7 : tensor([0.0044, 0.0540, 0.2420, 0.3991, 0.2420, 0.0540, 0.0044])
size=7 with +0.5 offset: tensor([0.0366, 0.1113, 0.2167, 0.2707, 0.2167, 0.1113, 0.0366])
size=9 : tensor([0.0033, 0.0238, 0.0972, 0.2260, 0.2994, 0.2260, 0.0972, 0.0238, 0.0033])
size=9 with +0.5 offset: tensor([0.0204, 0.0578, 0.1216, 0.1900, 0.2205, 0.1900, 0.1216, 0.0578, 0.0204])