Default Sigma Value in Gaussian Blur

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
grendell
Posts: 7
Joined: 2016-11-28T23:36:42-07:00
Authentication code: 1151

Default Sigma Value in Gaussian Blur

Post by grendell »

According to http://www.imagemagick.org/script/comma ... ssian-blur, sigma can be omitted on a Gaussian blur command, but I cannot locate a default value for use with MagickCore. Where can I find info like this? Thanks!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Default Sigma Value in Gaussian Blur

Post by fmw42 »

For radiusxsigma, if radius=0, then it is computed from the sigma by some formula that is between 2 and 3 time sigma. I am not sure the exact formula.

I have never used just the radius and do not know how that works or if that is a mistake in the documentation.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Default Sigma Value in Gaussian Blur

Post by snibgo »

From the source code (wand\mogrify.c MogrifyImage()) it seems that if sigma isn't set, it becomes 1.0. But if that's important to you, you should experiment to verify.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Default Sigma Value in Gaussian Blur

Post by fmw42 »

If that is the case, then using that default is not very good, since gaussian shapes get very close to zero by 3*sigma. So for any window with radius larger than 3, you are not changing the sigma and the rolloff and blur will be about the same. I suggest you use radiusxsigma=0xsigma and let the optimal radius be computed automatically.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Default Sigma Value in Gaussian Blur

Post by snibgo »

I agree, Fred. A little testing suggests that, yes, "-gaussian-blur R" gives a sigma of 1.0 for any radius R. So it is somewhat pointless. I would always use the "-gaussian-blur RxS" version.
snibgo's IM pages: im.snibgo.com
grendell
Posts: 7
Joined: 2016-11-28T23:36:42-07:00
Authentication code: 1151

Re: Default Sigma Value in Gaussian Blur

Post by grendell »

Thanks! 1.0 is actually what I had settled on while porting these commands, but compare was still coming back with (very minor) differences.

Now that I have everything ported (yay!), I'm going to go back and play with all the parameters, but I just needed a starting point. Thanks again!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Default Sigma Value in Gaussian Blur

Post by fmw42 »

I will try to document that r=1 if only R provided.

Snibgo, can you figure out the formula used for finding optimal R from the sigma? I looked at the code in gems.c for GetOptimalKernelWidth, but apart from the initial 2*ceil(R)+1, I do not understand the rest. Is there a simple formula or is it iterating in some way and if so, what is it iterating on? I tried a Google search, but came up empty for any meaningful description.

If I can get a simple formula or explanation, I will document that also.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Default Sigma Value in Gaussian Blur

Post by snibgo »

GetOptimalKernelWidth1D: when the given radius is zero, it calculates a one-dimenional blur for radius = 2, 3, ... until "value" is less than 1/2^Q, where Q=8, 16, 32 or 64, so "value" is effectively zero. I assume "value" is the tail end of the bell-shaped Gaussian curve. In other words, it finds the minimum width of the kernel that doesn't lose any data. If the kernel were larger, the new entries would be zero. This minimum depends on the Q-number and whether HDRI is used.

GetOptimalKernelWidth2D does the same, but for two-dimensional squares, and the tail end is measured at the corner of the square. So this will "clip" values at the edges (which I think is a bad idea; see below).

We can do the similar job at the command level, by making a single white pixel in a large black field, blurring with a given sigma (eg 1), trimming, and finding the dimension. I do this at Q8, Q16 and Q32, all integer (not HDRI), and Q32 HDRI.

Code: Select all

f:\web\im>c:\cygwin64\home\Alan\iminst8i\bin\convert xc:White -bordercolor Black -border 100   -gaussian-blur 50x1 -auto-level -trim +repage info:
xc:White XC 5x5 8-bit sRGB 0.109u 0:00.114

f:\web\im>c:\cygwin64\home\Alan\iminst16i\bin\convert xc:White -bordercolor Black -border 100   -gaussian-blur 50x1 -auto-level -trim +repage info:
xc:White XC 9x9 16-bit sRGB 0.109u 0:00.113

f:\web\im>c:\cygwin64\home\Alan\iminst32i\bin\convert xc:White -bordercolor Black -border 100   -gaussian-blur 50x1 -auto-level -trim +repage info:
xc:White XC 13x13 32-bit sRGB 0.125u 0:00.119

f:\web\im>c:\cygwin64\home\Alan\iminst32f\bin\convert xc:White -bordercolor Black -border 100   -gaussian-blur 50x1 -auto-level -trim +repage info:
xc:White XC 17x17 32-bit sRGB 0.108u 0:00.114
We can compare this to the kernel made by Q32 HDRI with "-gaussian-blur x1", when the radius isn't given:

Code: Select all

f:\web\im>%IMDEV%convert xc:White -bordercolor Black -border 100 -define showkernel=1 -gaussian-blur x1 -auto-level -trim +repage info:

Code: Select all

Kernel "Gaussian" of size 13x13+6+6 with values from 0 to 0.159155
The corner values are zero, but no other values are.

If we repeat the previous but with "-gaussian-blur Rx1" where R=1, 2, 3, ... we need R=9 to prevent any clipping. This gives a square kernel 19x19, but the first and last rows and columns are exactly zero, so the kernel is effectively only 17x17. This is the same result as the white pixel on black field test, for Q32 HDRI.

I conclude that the calculation IM makes for the radius in "-gaussian-blur x1" is too aggressive; the kernel is smaller than it should be.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Default Sigma Value in Gaussian Blur

Post by anthony »

fmw42 wrote:For radiusxsigma, if radius=0, then it is computed from the sigma by some formula that is between 2 and 3 time sigma. I am not sure the exact formula.

I have never used just the radius and do not know how that works or if that is a mistake in the documentation.
What I'm does is a little binary search to determine the radius (and thus the convolution kernal size) where the effect of the sigma falls below a unit value of 1 in the kernel. that is the largest radius for the convolution such that there is no more effect for the compile time data 'quality' of the Imagemagick.

As such the radius will be much smaller for a Q8 Imagemagick (data values from 0 to 255) than for a Q16 Imagemagick (data values from 0 to 65335). HDRI uses Q16 for this determination.

I mention this on the Convolve Examples page but only in passing...
http://www.imagemagick.org/Usage/convolve/#gaussian
IM usually calculates a radius that is approximately 3 times as big (actually the largest radius that will provide meaningful results), though it depends on the Compile-time Quality of your specific IM installation.
And again in Blurring Images....
http://www.imagemagick.org/Usage/blur/#blur
The ideal solution is to simply set radius to '0x' as shown by the last line of the above table. In that case the operator will try to automatically determine the best radius for the sigma given. The smallest radius IM would use is 3, and is typically 3 * sigma for a Q16 version of IM (a smaller radius is used for IM Q8, as it has less precision). The only time I would use a non-zero radius was for a very small sigma or for specialised blurs.
Also....
Due to the way IM handles 'x' style of arguments, the sigma in the above is optional. However it is the more important value, so it should be radius that is optional, as radius can be automatically determined. As such the a single value argument to these type of convolution operators is useless. This is unlikely to change as it has been this way for a very long time, and would break too many things.
NOTE you can use the morphology kernal generator to discover just how big the 1-D blur radius is. Easiest way is calaculate and show a 'comet' kernel (a half 1-D gaussian kernel), take its length and subtract 1 (for the origin pixel) to get the calculated radius.
http://www.imagemagick.org/Usage/convolve/#comet

Remember blur is actually a 2 pass operation.
http://www.imagemagick.org/Usage/convol ... an_vs_blur

Code: Select all

convert xc: -define showkernel=1 -morphology Convolve:0 "comet:0x1" null:
NOTE the kernels are all floating point. The limit if the smallest kernel value * the largest image value (determined by quality) > 1
IE: the next value in the guassian curve would have no significant effect on the image.

Also note the values in a guassian kernel are not real values of along a mathematical guarssian curve, but the area of under the guassian curve around that value (-0.5 to +0.5 around the pixel value). The real mathematical formula is actually known as the 'Err()' function. But it it vary close to a real Gaussian curve.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply