Ignore:
Timestamp:
04/25/12 00:47:23 (13 months ago)
Author:
anthony
Message:

Fix Gaussian Filter which was causing problems with Variable Blur

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ImageMagick/branches/ImageMagick-6/magick/resize.c

    r7591 r7625  
    198198  /* 
    199199    Cubic Filters using B,C determined values: 
    200        Mitchell-Netravali  B= 1/3 C= 1/3  "Balanced" cubic spline filter 
    201        Catmull-Rom         B= 0   C= 1/2  Interpolatory and exact on linears 
    202        Cubic B-Spline      B= 1   C= 0    Spline approximation of Gaussian 
    203        Hermite             B= 0   C= 0    Spline with small support (= 1) 
     200       Mitchell-Netravali  B = 1/3 C = 1/3  "Balanced" cubic spline filter 
     201       Catmull-Rom         B = 0   C = 1/2  Interpolatory and exact on linears 
     202       Cubic B-Spline      B = 1   C = 0    Spline approximation of Gaussian 
     203       Hermite             B = 0   C = 0    Spline with small support (= 1) 
    204204 
    205205    See paper by Mitchell and Netravali, Reconstruction Filters in Computer 
     
    239239{ 
    240240  /* 
    241     Gaussian with a fixed sigma = 1/2 
     241    Gaussian with a sigma = 1/2 (or as user specified) 
    242242 
    243243    Gaussian Formula (1D) ... 
    244         exp( -(x^2)/((2.0*sigma^2) ) / sqrt(2*PI)sigma^2)) 
     244        exp( -(x^2)/((2.0*sigma^2) ) / (sqrt(2*PI)*sigma^2)) 
     245 
     246    Gaussian Formula (2D) ... 
     247        exp( -(x^2+y^2)/(2.0*sigma^2) ) / (PI*sigma^2) ) 
     248    or for radius 
     249        exp( -(r^2)/(2.0*sigma^2) ) / (PI*sigma^2) ) 
     250 
     251    Note that it is only a change from 1-d to radial form is in the 
     252    normalization multiplier which is not needed or used when Gaussian is used 
     253    as a filter. 
     254 
    245255    The constants are pre-calculated... 
    246         exp( -coeff[0]*(x^2)) ) * coeff[1] 
    247     However the multiplier coefficent (1) is not needed and not used. 
    248  
    249     Gaussian Formula (2D) ... 
    250         exp( -(x^2)/((2.0*sigma^2) ) / (PI*sigma^2) ) 
    251     Note that it is only a change in the normalization multiplier 
    252     which is not needed or used when gausian is used as a filter. 
     256 
     257        coeff[0]=sigma; 
     258        coeff[1]=1.0/(2.0*sigma^2); 
     259        coeff[2]=1.0/(sqrt(2*PI)*sigma^2); 
     260 
     261        exp( -coeff[1]*(x^2)) ) * coeff[2]; 
     262 
     263    However the multiplier coeff[1] is not needed and not used. 
    253264 
    254265    This separates the gaussian 'sigma' value from the 'blur/support' 
     
    257268    small. 
    258269  */ 
    259   return(exp((double)(-resize_filter->coefficient[0]*x*x))); 
     270  return(exp((double)(-resize_filter->coefficient[1]*x*x))); 
    260271} 
    261272 
     
    287298  /* 
    288299    Kaiser Windowing Function (bessel windowing) 
    289     Alpha (c[0]) is a free value from 5 to 8 (defaults to 6.5). 
    290     A scaling factor (c[1]) is not needed as filter is normalized 
     300    Alpha (coeff[0]) is a free value from 5 to 8 (defaults to 6.5). 
     301    A scaling factor (coeff[1]) is not actually needed as filter will 
     302    automatically be normalized. 
    291303  */ 
    292304  return(resize_filter->coefficient[1]* 
     
    684696 
    685697  /* 
    686     Table Mapping given Filter, into Weighting and Windowing functions. A 
    687     'Box' windowing function means its a simble non-windowed filter.  An 
    688     'SincFast' filter function could be upgraded to a 'Jinc' filter if a 
    689     "cylindrical", unless a 'Sinc' or 'SincFast' filter was specifically 
    690     requested. 
    691  
    692     WARNING: The order of this tabel must match the order of the FilterTypes 
     698    Table Mapping given Filter, into Weighting and Windowing functions. 
     699    A 'Box' windowing function means its a simble non-windowed filter. 
     700    An 'SincFast' filter function could be upgraded to a 'Jinc' filter if a 
     701    "cylindrical" is requested, unless a 'Sinc' or 'SincFast' filter was 
     702    specifically requested by the user. 
     703 
     704    WARNING: The order of this table must match the order of the FilterTypes 
    693705    enumeration specified in "resample.h", or the filter names will not match 
    694706    the filter being setup. 
    695707 
    696     You can check filter setups with the "filter:verbose" setting. 
     708    You can check filter setups with the "filter:verbose" expert setting. 
    697709  */ 
    698710  static struct 
     
    747759    MagickRealType 
    748760      (*function)(const MagickRealType,const ResizeFilter*), 
    749       lobes, /* Default lobes/support size of the weighting filter. */ 
    750       scale,  /* Support when function used as a windowing function 
     761      support, /* Default lobes/support size of the weighting filter. */ 
     762      scale,   /* Support when function used as a windowing function 
    751763                 Typically equal to the location of the first zero crossing. */ 
    752       B,C;    /* BC-spline coefficients, ignored if not a CubicBC filter. */ 
     764      B,C;     /* BC-spline coefficients, ignored if not a CubicBC filter. */ 
    753765  } const filters[SentinelFilter] = 
    754766  { 
     
    766778    { Hamming,   1.0, 1.0, 0.0, 0.0 }, /* Hamming, '' variation       */ 
    767779    { Blackman,  1.0, 1.0, 0.0, 0.0 }, /* Blackman, 2*cosine window   */ 
    768     { Gaussian,  2.0, 1.5, 0.0, 0.0 }, /* Gaussian                    */ 
     780    { Gaussian,  1.5, 1.5, 0.0, 0.0 }, /* Gaussian                    */ 
    769781    { Quadratic, 1.5, 1.5, 0.0, 0.0 }, /* Quadratic gaussian          */ 
    770782    { CubicBC,   2.0, 2.0, 1.0, 0.0 }, /* Cubic B-Spline (B=1,C=0)    */ 
     
    891903  /* Assign the real functions to use for the filters selected. */ 
    892904  resize_filter->filter=filters[filter_type].function; 
    893   resize_filter->support=filters[filter_type].lobes; 
     905  resize_filter->support=filters[filter_type].support; 
    894906  resize_filter->window=filters[window_type].function; 
    895907  resize_filter->scale=filters[window_type].scale; 
     
    934946 
    935947  /* User Gaussian Sigma Override - no support change */ 
    936   value=0.5;    /* guassian sigma default, half pixel */ 
    937   if ( GaussianFilter ) { 
     948  if (resize_filter->filter == Gaussian) { 
     949    value=0.5;    /* guassian sigma default, half pixel */ 
    938950    artifact=GetImageArtifact(image,"filter:sigma"); 
    939951    if (artifact != (const char *) NULL) 
    940952      value=StringToDouble(artifact,(char **) NULL); 
    941953    /* Define coefficents for Gaussian */ 
    942     resize_filter->coefficient[0]=1.0/(2.0*value*value); /* X scaling */ 
    943     resize_filter->coefficient[1]=(MagickRealType) (1.0/(Magick2PI*value* 
    944       value)); /* normalization */ 
     954    resize_filter->coefficient[0]=value;                 /* note sigma too */ 
     955    resize_filter->coefficient[1]=1.0/(2.0*value*value); /* sigma scaling */ 
     956    resize_filter->coefficient[2]=1.0/(Magick2PI*value*value); 
     957       /* normalization - not actually needed or used! */ 
     958    if ( value > 0.5 ) 
     959      resize_filter->support *= value/0.5;  /* increase support */ 
    945960  } 
     961 
    946962  /* User Kaiser Alpha Override - no support change */ 
    947   if ( KaiserFilter ) { 
     963  if (resize_filter->filter == Kaiser) { 
    948964    value=6.5; /* default alpha value for Kaiser bessel windowing function */ 
    949965    artifact=GetImageArtifact(image,"filter:alpha"); 
     
    951967      value=StringToDouble(artifact,(char **) NULL); 
    952968    /* Define coefficents for Kaiser Windowing Function */ 
    953     resize_filter->coefficient[0]=value;         /* X scaling */ 
     969    resize_filter->coefficient[0]=value;         /* alpha */ 
    954970    resize_filter->coefficient[1]=1.0/I0(value); /* normalization */ 
    955971  } 
     
    10941110        if ( filter_type == GaussianFilter ) 
    10951111          (void) FormatLocaleFile(stdout,"# gaussian_sigma = %.*g\n", 
    1096                GetMagickPrecision(), (double)value); 
     1112               GetMagickPrecision(), (double)resize_filter->coefficient[0]); 
    10971113        if ( filter_type == KaiserFilter ) 
    10981114          (void) FormatLocaleFile(stdout,"# kaiser_alpha = %.*g\n", 
    1099                GetMagickPrecision(), (double)value); 
     1115               GetMagickPrecision(), (double)resize_filter->coefficient[0]); 
    11001116        (void) FormatLocaleFile(stdout,"# practical_support = %.*g\n", 
    11011117             GetMagickPrecision(), (double)support); 
Note: See TracChangeset for help on using the changeset viewer.