Page 1 of 1

Gaussian Curve has Changed in resize.c

Posted: 2010-09-09T22:44:58-07:00
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:

Re: Gaussian Curve has Changed in resize.c

Posted: 2010-09-10T07:26:54-07:00
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