change parameters of vips_gaussblur()

sorry :-(

The old param (passing sigma*2 as an int) were just too confusing
coming from other packages. This new behaviour matches ImageMagick, and
almost everyone else in the world.

A new optional param lets you set the minimum amplitude as well.
This commit is contained in:
John Cupitt 2014-11-19 12:27:26 +00:00
parent 2a4f56ff9f
commit 384a5e05dc
6 changed files with 36 additions and 29 deletions

View File

@ -2,6 +2,7 @@
- better default resolution for png load
- better pbm (one bit) load, better pfm (float) load/save
- added pbm (one bit) save
- changed vips_gaussblur() parameters, sorry
25/7/14 started 7.41.0
- start working on --disable-deprecated

3
TODO
View File

@ -1,3 +1,6 @@
- use vips_gaussblur() in vips_resize(), and vipsthumbnail.c
- test building without cpp
need to add introspection.m4 to m4/ dir?

View File

@ -2,6 +2,8 @@
*
* 15/11/13
* - from vips_sharpen()
* 19/11/14
* - change parameters to be more imagemagick-like
*/
/*
@ -52,7 +54,8 @@ typedef struct _VipsGaussblur {
VipsImage *in;
VipsImage *out;
int radius;
gdouble sigma;
gdouble min_ampl;
VipsPrecision precision;
} VipsGaussblur;
@ -70,10 +73,7 @@ vips_gaussblur_build( VipsObject *object )
if( VIPS_OBJECT_CLASS( vips_gaussblur_parent_class )->build( object ) )
return( -1 );
/* Stop at 20% of max ... bit mean, but means mask radius is roughly
* right.
*/
if( vips_gaussmat( &t[0], gaussblur->radius / 2.0, 0.2,
if( vips_gaussmat( &t[0], gaussblur->sigma, gaussblur->min_ampl,
"separable", TRUE,
"integer", gaussblur->precision != VIPS_PRECISION_FLOAT,
NULL ) )
@ -125,12 +125,19 @@ vips_gaussblur_class_init( VipsGaussblurClass *class )
VIPS_ARGUMENT_REQUIRED_OUTPUT,
G_STRUCT_OFFSET( VipsGaussblur, out ) );
VIPS_ARG_INT( class, "radius", 3,
_( "radius" ),
_( "Mask radius" ),
VIPS_ARG_DOUBLE( class, "sigma", 3,
_( "Sigma" ),
_( "Sigma of gaussian" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGaussblur, radius ),
1, 1000000, 3 );
G_STRUCT_OFFSET( VipsGaussblur, sigma ),
0.01, 1000, 1.5 );
VIPS_ARG_DOUBLE( class, "min_ampl", 3,
_( "Minimum amplitude" ),
_( "Minimum amplitude of gaussian" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsGaussblur, min_ampl ),
0.001, 1.0, 0.2 );
VIPS_ARG_ENUM( class, "precision", 4,
_( "Precision" ),
@ -144,7 +151,8 @@ vips_gaussblur_class_init( VipsGaussblurClass *class )
static void
vips_gaussblur_init( VipsGaussblur *gaussblur )
{
gaussblur->radius = 3;
gaussblur->sigma = 1.5;
gaussblur->min_ampl = 0.2;
gaussblur->precision = VIPS_PRECISION_INTEGER;
}
@ -152,31 +160,30 @@ vips_gaussblur_init( VipsGaussblur *gaussblur )
* vips_gaussblur:
* @in: input image
* @out: output image
* @radius: how large a mask to use
* @sigma: how large a mask to use
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* @precision: #VipsPrecision for blur
* @precision: #VipsPrecision for blur, default VIPS_PRECISION_INTEGER
* @min_ampl: minimum amplitude, default 0.2
*
* This operator runs vips_gaussmat() and vips_convsep() for you on an image.
* Set @min_ampl smaller to generate a larger, more accurate mask. Set @sigma
* larger to make the blur more blurry.
*
* @radius is not used directly. Instead the standard deviation of
* vips_gaussmat() is set to @radius / 2.0 and the minimum amplitude set to
* 20%. This gives a mask radius of approximately @radius pixels.
*
* See also: vips_gaussmat(), vips_conv().
* See also: vips_gaussmat(), vips_convsep().
*
* Returns: 0 on success, -1 on error.
*/
int
vips_gaussblur( VipsImage *in, VipsImage **out, int radius, ... )
vips_gaussblur( VipsImage *in, VipsImage **out, double sigma, ... )
{
va_list ap;
int result;
va_start( ap, radius );
result = vips_call_split( "gaussblur", ap, in, out, radius );
va_start( ap, sigma );
result = vips_call_split( "gaussblur", ap, in, out, sigma );
va_end( ap );
return( result );

View File

@ -164,7 +164,7 @@ vips_gaussmat_class_init( VipsGaussmatClass *class )
0.000001, 10000.0, 1.0 );
VIPS_ARG_DOUBLE( class, "min_ampl", 3,
_( "Width" ),
_( "Minimum amplitude" ),
_( "Minimum amplitude of Gaussian" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGaussmat, min_ampl ),

View File

@ -60,7 +60,7 @@ int vips_convsep( VipsImage *in, VipsImage **out, VipsImage *mask, ... )
int vips_sharpen( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
int vips_gaussblur( VipsImage *in, VipsImage **out, int radius, ... )
int vips_gaussblur( VipsImage *in, VipsImage **out, double sigma, ... )
__attribute__((sentinel));
int vips_spcor( VipsImage *in, VipsImage *ref, VipsImage **out, ... )

View File

@ -176,11 +176,7 @@ vips_resize_build( VipsObject *object )
sigma = ((1.0 / residual) - 0.5) / 1.5;
if( residual < 1.0 &&
sigma > 0.1 ) {
if( vips_gaussmat( &t[1], sigma, 0.2,
"separable", TRUE,
"integer", TRUE,
NULL ) ||
vips_convsep( in, &t[2], t[1], NULL ) )
if( vips_gaussblur( in, &t[2], sigma, NULL ) )
return( -1 );
in = t[2];
}