vips_conv*() default to float
we had INT as the default, but this will cause serious precision loss with many masks ... instead, have float (always correct) as the default and let people turn on int if they cn
This commit is contained in:
parent
1504fb0249
commit
3019e5966b
@ -4,10 +4,11 @@
|
|||||||
constant image
|
constant image
|
||||||
- add new_from_image() to Python as well
|
- add new_from_image() to Python as well
|
||||||
- slight change to cpp new_from_image() to match py/C behaviour
|
- slight change to cpp new_from_image() to match py/C behaviour
|
||||||
|
- vips_conv(), vips_compass(), vips_convsep() default to FLOAT precision
|
||||||
|
|
||||||
23/4/17 started 8.5.5
|
23/4/17 started 8.5.5
|
||||||
- doc polishing
|
- doc polishing
|
||||||
- more improvements for tuncated PNG files, thanks juyunsang
|
- more improvements for truncated PNG files, thanks juyunsang
|
||||||
|
|
||||||
23/4/17 started 8.5.4
|
23/4/17 started 8.5.4
|
||||||
- don't depend on image width when setting n_lines, thanks kleisauke
|
- don't depend on image width when setting n_lines, thanks kleisauke
|
||||||
|
2
TODO
2
TODO
@ -1,3 +1,5 @@
|
|||||||
|
- vips_compass() needs docs
|
||||||
|
|
||||||
- cpp bandjoin should use bandjoin_const() where possibel ... currently
|
- cpp bandjoin should use bandjoin_const() where possibel ... currently
|
||||||
uses new_from_image
|
uses new_from_image
|
||||||
|
|
||||||
|
@ -193,8 +193,12 @@ vips_smartcrop_attention( VipsSmartcrop *smartcrop,
|
|||||||
/* Sobel edge-detect on L.
|
/* Sobel edge-detect on L.
|
||||||
*/
|
*/
|
||||||
if( vips_extract_band( t[1], &t[2], 0, NULL ) ||
|
if( vips_extract_band( t[1], &t[2], 0, NULL ) ||
|
||||||
vips_conv( t[2], &t[3], t[21], NULL ) ||
|
vips_conv( t[2], &t[3], t[21],
|
||||||
vips_conv( t[2], &t[4], t[22], NULL ) ||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
|
vips_conv( t[2], &t[4], t[22],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_abs( t[3], &t[5], NULL ) ||
|
vips_abs( t[3], &t[5], NULL ) ||
|
||||||
vips_abs( t[4], &t[6], NULL ) ||
|
vips_abs( t[4], &t[6], NULL ) ||
|
||||||
vips_add( t[5], t[6], &t[7], NULL ) )
|
vips_add( t[5], t[6], &t[7], NULL ) )
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
*
|
*
|
||||||
* 23/10/13
|
* 23/10/13
|
||||||
* - from vips_conv()
|
* - from vips_conv()
|
||||||
|
* 8/5/17
|
||||||
|
* - default to float ... int will often lose precision and should not be
|
||||||
|
* the default
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -172,7 +175,7 @@ vips_compass_class_init( VipsCompassClass *class )
|
|||||||
_( "Convolve with this precision" ),
|
_( "Convolve with this precision" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsCompass, precision ),
|
G_STRUCT_OFFSET( VipsCompass, precision ),
|
||||||
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
VIPS_TYPE_PRECISION, VIPS_PRECISION_FLOAT );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "layers", 204,
|
VIPS_ARG_INT( class, "layers", 204,
|
||||||
_( "Layers" ),
|
_( "Layers" ),
|
||||||
@ -196,7 +199,7 @@ vips_compass_init( VipsCompass *compass )
|
|||||||
compass->times = 2;
|
compass->times = 2;
|
||||||
compass->angle = VIPS_ANGLE45_D90;
|
compass->angle = VIPS_ANGLE45_D90;
|
||||||
compass->combine = VIPS_COMBINE_MAX;
|
compass->combine = VIPS_COMBINE_MAX;
|
||||||
compass->precision = VIPS_PRECISION_INTEGER;
|
compass->precision = VIPS_PRECISION_FLOAT;
|
||||||
compass->layers = 5;
|
compass->layers = 5;
|
||||||
compass->cluster = 1;
|
compass->cluster = 1;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
*
|
*
|
||||||
* 12/8/13
|
* 12/8/13
|
||||||
* - from vips_hist_cum()
|
* - from vips_hist_cum()
|
||||||
|
* 8/5/17
|
||||||
|
* - default to float ... int will often lose precision and should not be
|
||||||
|
* the default
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -137,7 +140,7 @@ vips_conv_class_init( VipsConvClass *class )
|
|||||||
_( "Convolve with this precision" ),
|
_( "Convolve with this precision" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsConv, precision ),
|
G_STRUCT_OFFSET( VipsConv, precision ),
|
||||||
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
VIPS_TYPE_PRECISION, VIPS_PRECISION_FLOAT );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "layers", 104,
|
VIPS_ARG_INT( class, "layers", 104,
|
||||||
_( "Layers" ),
|
_( "Layers" ),
|
||||||
@ -158,7 +161,7 @@ vips_conv_class_init( VipsConvClass *class )
|
|||||||
static void
|
static void
|
||||||
vips_conv_init( VipsConv *conv )
|
vips_conv_init( VipsConv *conv )
|
||||||
{
|
{
|
||||||
conv->precision = VIPS_PRECISION_INTEGER;
|
conv->precision = VIPS_PRECISION_FLOAT;
|
||||||
conv->layers = 5;
|
conv->layers = 5;
|
||||||
conv->cluster = 1;
|
conv->cluster = 1;
|
||||||
}
|
}
|
||||||
@ -187,22 +190,23 @@ vips_conv_init( VipsConv *conv )
|
|||||||
*
|
*
|
||||||
* where scale and offset are part of @mask.
|
* where scale and offset are part of @mask.
|
||||||
*
|
*
|
||||||
|
* By default, @precision is
|
||||||
|
* #VIPS_PRECISION_FLOAT. The output image
|
||||||
|
* is always #VIPS_FORMAT_FLOAT unless @in is #VIPS_FORMAT_DOUBLE, in which case
|
||||||
|
* @out is also #VIPS_FORMAT_DOUBLE.
|
||||||
|
*
|
||||||
* If @precision is #VIPS_PRECISION_INTEGER, then
|
* If @precision is #VIPS_PRECISION_INTEGER, then
|
||||||
* elements of @mask are converted to
|
* elements of @mask are converted to
|
||||||
* integers before convolution, using rint(),
|
* integers before convolution, using rint(),
|
||||||
* and the output image
|
* and the output image
|
||||||
* always has the same #VipsBandFormat as the input image.
|
* always has the same #VipsBandFormat as the input image.
|
||||||
*
|
*
|
||||||
* For #VIPS_FORMAT_UCHAR images, vips_conv() uses a fast vector path based on
|
* For #VIPS_FORMAT_UCHAR images and #VIPS_PRECISION_INTEGER @precision,
|
||||||
|
* vips_conv() uses a fast vector path based on
|
||||||
* fixed-point arithmetic. This can produce slightly different results.
|
* fixed-point arithmetic. This can produce slightly different results.
|
||||||
* Disable the vector path with `--vips-novector` or `VIPS_NOVECTOR` or
|
* Disable the vector path with `--vips-novector` or `VIPS_NOVECTOR` or
|
||||||
* vips_vector_set_enabled().
|
* vips_vector_set_enabled().
|
||||||
*
|
*
|
||||||
* If @precision is #VIPS_PRECISION_FLOAT then the convolution is performed
|
|
||||||
* with floating-point arithmetic. The output image
|
|
||||||
* is always #VIPS_FORMAT_FLOAT unless @in is #VIPS_FORMAT_DOUBLE, in which case
|
|
||||||
* @out is also #VIPS_FORMAT_DOUBLE.
|
|
||||||
*
|
|
||||||
* If @precision is #VIPS_PRECISION_APPROXIMATE then, like
|
* If @precision is #VIPS_PRECISION_APPROXIMATE then, like
|
||||||
* #VIPS_PRECISION_INTEGER, @mask is converted to int before convolution, and
|
* #VIPS_PRECISION_INTEGER, @mask is converted to int before convolution, and
|
||||||
* the output image
|
* the output image
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
*
|
*
|
||||||
* 23/10/13
|
* 23/10/13
|
||||||
* - from vips_convsep()
|
* - from vips_convsep()
|
||||||
|
* 8/5/17
|
||||||
|
* - default to float ... int will often lose precision and should not be
|
||||||
|
* the default
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -128,7 +131,7 @@ vips_convsep_class_init( VipsConvsepClass *class )
|
|||||||
_( "Convolve with this precision" ),
|
_( "Convolve with this precision" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsConvsep, precision ),
|
G_STRUCT_OFFSET( VipsConvsep, precision ),
|
||||||
VIPS_TYPE_PRECISION, VIPS_PRECISION_INTEGER );
|
VIPS_TYPE_PRECISION, VIPS_PRECISION_FLOAT );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "layers", 204,
|
VIPS_ARG_INT( class, "layers", 204,
|
||||||
_( "Layers" ),
|
_( "Layers" ),
|
||||||
@ -149,7 +152,7 @@ vips_convsep_class_init( VipsConvsepClass *class )
|
|||||||
static void
|
static void
|
||||||
vips_convsep_init( VipsConvsep *convsep )
|
vips_convsep_init( VipsConvsep *convsep )
|
||||||
{
|
{
|
||||||
convsep->precision = VIPS_PRECISION_INTEGER;
|
convsep->precision = VIPS_PRECISION_FLOAT;
|
||||||
convsep->layers = 5;
|
convsep->layers = 5;
|
||||||
convsep->cluster = 1;
|
convsep->cluster = 1;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,9 @@ vips_sharpen_build( VipsObject *object )
|
|||||||
*/
|
*/
|
||||||
if( vips_extract_band( in, &args[0], 0, NULL ) ||
|
if( vips_extract_band( in, &args[0], 0, NULL ) ||
|
||||||
vips_extract_band( in, &t[3], 1, "n", in->Bands - 1, NULL ) ||
|
vips_extract_band( in, &t[3], 1, "n", in->Bands - 1, NULL ) ||
|
||||||
vips_convsep( args[0], &args[1], t[1], NULL ) )
|
vips_convsep( args[0], &args[1], t[1],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
|
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
|
||||||
|
@ -2283,6 +2283,7 @@ im_compass( VipsImage *in, VipsImage *out, INTMASK *mask )
|
|||||||
if( vips_compass( in, &t2, t1,
|
if( vips_compass( in, &t2, t1,
|
||||||
"times", 8,
|
"times", 8,
|
||||||
"angle", VIPS_ANGLE45_D45,
|
"angle", VIPS_ANGLE45_D45,
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
NULL ) ) {
|
NULL ) ) {
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -2308,6 +2309,7 @@ im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
if( vips_compass( in, &t2, t1,
|
if( vips_compass( in, &t2, t1,
|
||||||
"times", 4,
|
"times", 4,
|
||||||
"angle", VIPS_ANGLE45_D45,
|
"angle", VIPS_ANGLE45_D45,
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
NULL ) ) {
|
NULL ) ) {
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -2334,6 +2336,7 @@ im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
"times", 2,
|
"times", 2,
|
||||||
"angle", VIPS_ANGLE45_D90,
|
"angle", VIPS_ANGLE45_D90,
|
||||||
"combine", VIPS_COMBINE_SUM,
|
"combine", VIPS_COMBINE_SUM,
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
NULL ) ) {
|
NULL ) ) {
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -2364,6 +2367,7 @@ im_convsep( IMAGE *in, IMAGE *out, INTMASK *mask )
|
|||||||
im_imask2vips( mask, t1 ) )
|
im_imask2vips( mask, t1 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( vips_convsep( in, &t2, t1,
|
if( vips_convsep( in, &t2, t1,
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
NULL ) ) {
|
NULL ) ) {
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -2393,9 +2397,7 @@ im_convsep_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
|
|||||||
if( !(t1 = vips_image_new()) ||
|
if( !(t1 = vips_image_new()) ||
|
||||||
im_mask2vips( mask, t1 ) )
|
im_mask2vips( mask, t1 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( vips_convsep( in, &t2, t1,
|
if( vips_convsep( in, &t2, t1, NULL ) ) {
|
||||||
"precision", VIPS_PRECISION_FLOAT,
|
|
||||||
NULL ) ) {
|
|
||||||
g_object_unref( t1 );
|
g_object_unref( t1 );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -2561,12 +2563,18 @@ im_contrast_surface( IMAGE *in, IMAGE *out, int half_win_size, int spacing )
|
|||||||
for( x = 0; x < size; x++ )
|
for( x = 0; x < size; x++ )
|
||||||
*VIPS_MATRIX( t[8], x, y ) = 1.0;
|
*VIPS_MATRIX( t[8], x, y ) = 1.0;
|
||||||
|
|
||||||
if( vips_conv( in, &t[2], t[0], NULL ) ||
|
if( vips_conv( in, &t[2], t[0],
|
||||||
vips_conv( in, &t[3], t[1], NULL ) ||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
|
vips_conv( in, &t[3], t[1],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_abs( t[2], &t[4], NULL ) ||
|
vips_abs( t[2], &t[4], NULL ) ||
|
||||||
vips_abs( t[3], &t[5], NULL ) ||
|
vips_abs( t[3], &t[5], NULL ) ||
|
||||||
vips_add( t[4], t[5], &t[6], NULL ) ||
|
vips_add( t[4], t[5], &t[6], NULL ) ||
|
||||||
vips_conv( t[6], &t[7], t[8], NULL ) ||
|
vips_conv( t[6], &t[7], t[8],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_subsample( t[7], &t[9], spacing, spacing, NULL ) ||
|
vips_subsample( t[7], &t[9], spacing, spacing, NULL ) ||
|
||||||
vips_image_write( t[9], out ) )
|
vips_image_write( t[9], out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -90,7 +90,9 @@ vips_hist_ismonotonic_build( VipsObject *object )
|
|||||||
|
|
||||||
/* We want >=128 everywhere, ie. no -ve transitions.
|
/* We want >=128 everywhere, ie. no -ve transitions.
|
||||||
*/
|
*/
|
||||||
if( vips_conv( ismonotonic->in, &t[1], t[0], NULL ) ||
|
if( vips_conv( ismonotonic->in, &t[1], t[0],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_moreeq_const1( t[1], &t[2], 128, NULL ) ||
|
vips_moreeq_const1( t[1], &t[2], 128, NULL ) ||
|
||||||
vips_min( t[2], &m, NULL ) )
|
vips_min( t[2], &m, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -92,7 +92,9 @@ vips_countlines_build( VipsObject *object )
|
|||||||
case VIPS_DIRECTION_HORIZONTAL:
|
case VIPS_DIRECTION_HORIZONTAL:
|
||||||
if( !(t[0] = vips_image_new_matrixv( 1, 2, -1.0, 1.0 )) ||
|
if( !(t[0] = vips_image_new_matrixv( 1, 2, -1.0, 1.0 )) ||
|
||||||
vips_moreeq_const1( in, &t[1], 128, NULL ) ||
|
vips_moreeq_const1( in, &t[1], 128, NULL ) ||
|
||||||
vips_conv( t[1], &t[2], t[0], NULL ) ||
|
vips_conv( t[1], &t[2], t[0],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_project( t[2], &t[3], &t[4], NULL ) ||
|
vips_project( t[2], &t[3], &t[4], NULL ) ||
|
||||||
vips_avg( t[3], &nolines, NULL ) )
|
vips_avg( t[3], &nolines, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -101,7 +103,9 @@ vips_countlines_build( VipsObject *object )
|
|||||||
case VIPS_DIRECTION_VERTICAL:
|
case VIPS_DIRECTION_VERTICAL:
|
||||||
if( !(t[0] = vips_image_new_matrixv( 2, 1, -1.0, 1.0 )) ||
|
if( !(t[0] = vips_image_new_matrixv( 2, 1, -1.0, 1.0 )) ||
|
||||||
vips_moreeq_const1( in, &t[1], 128, NULL ) ||
|
vips_moreeq_const1( in, &t[1], 128, NULL ) ||
|
||||||
vips_conv( t[1], &t[2], t[0], NULL ) ||
|
vips_conv( t[1], &t[2], t[0],
|
||||||
|
"precision", VIPS_PRECISION_INTEGER,
|
||||||
|
NULL ) ||
|
||||||
vips_project( t[2], &t[3], &t[4], NULL ) ||
|
vips_project( t[2], &t[3], &t[4], NULL ) ||
|
||||||
vips_avg( t[4], &nolines, NULL ) )
|
vips_avg( t[4], &nolines, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
Loading…
Reference in New Issue
Block a user