Gaussian Curve has Changed in resize.c

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Gaussian Curve has Changed in resize.c

Post by anthony »

The Gaussian curve and its weighting has changed

Old....
Image
From the function...

Code: Select all

static MagickRealType Gaussian(const MagickRealType x,
  const ResizeFilter *magick_unused(resize_filter))
{
  return(exp((double) (-2.0*x*x))*sqrt(2.0/MagickPI));
}
now it is...
Image
generated by the function

Code: Select all

static MagickRealType Gaussian(const MagickRealType x,
  const ResizeFilter *magick_unused(resize_filter))
{ 
  /*
    Unnormalized Gaussian with variance sqrt(pi)/(4*sqrt(2)):
      exp(-2 x^2/sqrt(pi/2))
  */
  const MagickRealType alpha = -sqrt((double) (8.0/MagickPIL));
  return(exp((double) (alpha*x*x)));
}
It has changed. and quite dramatically.

As the curve is now higher, the normalization of weightings will cause the spread to be
lower, which makes the curve much closer to both the Quadratic and Cubic filter curves
This may mean that the new form is the 'correct' one. But I will not know unless I can
review my Gaussian research notes (at home).

Nicholas, can you shed some light on this?

graphs were generated from the filter can be extracted using

Code: Select all

   convert xc: -filter Gaussian -set option:filter:verbose 1 -resize 2x2 null:
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Gaussian Curve has Changed in resize.c

Post by anthony »

It is strange, but the 1D Gaussian blur filter for Convolve does not seem to involve PI within the exp() function arguments. a 2D Gaussian does but not a 1D Gaussian which is what a resize Gaussian filter should be.

Something seems off to me. The original "zoom" program has Gaussian filter defined as

Code: Select all

   double filt_gaussian(double x, void *d)>/* Gaussian (infinite) */
{
    return exp(-2.*x*x)*sqrt(2./PI);
}
Yes the second formula is WRONG. The constant was shifted inside the exp() when it was outside in the original version. That means the 'sigma' was no longer 1/2 but something else.
The result Gaussian became more 'blurry' that it should be.

Using the optimized formula used for convolution kernels, I get the replacement formula of...

Code: Select all

   const MagickRealType alpha=2.0/MAGICKSQ2PI;
   return (exp(-(double)(2.0*x*x))*alpha);
That works and removes the need for the sqrt in the constant calculation, so should optimize very well. And even matches the definition used to define 1D blur convolution kernels of sigma = 1/2
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply