wrap im_global_balance*() as a class

This commit is contained in:
John Cupitt 2014-05-26 15:02:15 +01:00
parent e2cda919ea
commit 781a7d4dc9
7 changed files with 165 additions and 58 deletions

View File

@ -33,7 +33,8 @@
- added im_tile_cache_random() to help nip2
- added hough_circle() to vips7 C++ API
- added Travis CI config, thanks Lovell
- im_*merge(), im_*mosaic(), im_match*() redone as classes
- im_*merge(), im_*mosaic(), im_match*(), im_global_balance*() redone as
classes
6/3/14 started 7.38.6
- grey ramp minimum was wrong

4
TODO
View File

@ -1,12 +1,12 @@
- quickly wrap the useful bits of mosaicing/
- quickly wrap the useful bits of mosaicing
nip2 uses:
im_*merge() done
im_*mosaic() done
im_match_linear*() done
im_global_balancef()
im_global_balancef() done
im_remosaic()
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.

View File

@ -5095,3 +5095,42 @@ im_match_linear( IMAGE *ref, IMAGE *sec, IMAGE *out,
return( 0 );
}
int
im_global_balance( IMAGE *in, IMAGE *out, double gamma )
{
VipsImage *x;
if( vips_globalbalance( in, &x,
"gamma", gamma,
"int_output", TRUE,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int
im_global_balancef( IMAGE *in, IMAGE *out, double gamma )
{
VipsImage *x;
if( vips_globalbalance( in, &x,
"gamma", gamma,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}

View File

@ -48,10 +48,8 @@ int vips_match( VipsImage *ref, VipsImage *sec, VipsImage **out,
int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2, ... )
__attribute__((sentinel));
int vips_globalbalance( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
#include <vips/vips.h>
@ -80,9 +78,6 @@ int im_tbmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out,
int balancetype,
int mwidth );
int im_global_balance( VipsImage *in, VipsImage *out, double gamma );
int im_global_balancef( VipsImage *in, VipsImage *out, double gamma );
int im_correl( VipsImage *ref, VipsImage *sec,
int xref, int yref, int xsec, int ysec,
int hwindowsize, int hsearchsize,

View File

@ -1061,6 +1061,9 @@ int im_match_linear_search( VipsImage *ref, VipsImage *sec, VipsImage *out,
int xr2, int yr2, int xs2, int ys2,
int hwindowsize, int hsearchsize );
int im_global_balance( VipsImage *in, VipsImage *out, double gamma );
int im_global_balancef( VipsImage *in, VipsImage *out, double gamma );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -1705,13 +1705,108 @@ transformf( JoinNode *node, double *gamma )
return( out );
}
typedef struct {
VipsOperation parent_instance;
VipsImage *in;
VipsImage *out;
gboolean int_output;
double gamma;
} VipsGlobalbalance;
typedef VipsOperationClass VipsGlobalbalanceClass;
G_DEFINE_TYPE( VipsGlobalbalance, vips_globalbalance, VIPS_TYPE_OPERATION );
static int
vips_globalbalance_build( VipsObject *object )
{
VipsGlobalbalance *globalbalance = (VipsGlobalbalance *) object;
SymbolTable *st;
transform_fn trn;
g_object_set( globalbalance, "out", vips_image_new(), NULL );
if( VIPS_OBJECT_CLASS( vips_globalbalance_parent_class )->
build( object ) )
return( -1 );
if( !(st = im__build_symtab( globalbalance->out, SYM_TAB_SIZE )) ||
analyse_mosaic( st, globalbalance->in ) ||
find_factors( st, globalbalance->gamma ) )
return( -1 );
trn = globalbalance->int_output ?
(transform_fn) transform : (transform_fn) transformf;
if( im__build_mosaic( st, globalbalance->out,
trn, &globalbalance->gamma ) )
return( -1 );
return( 0 );
}
static void
vips_globalbalance_class_init( VipsGlobalbalanceClass *class )
{
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
VipsObjectClass *object_class = (VipsObjectClass *) class;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "globalbalance";
object_class->description = _( "global balance an image mosaic" );
object_class->build = vips_globalbalance_build;
VIPS_ARG_IMAGE( class, "in", 1,
_( "Input" ),
_( "Input image" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGlobalbalance, in ) );
VIPS_ARG_IMAGE( class, "out", 2,
_( "Output" ),
_( "Output image" ),
VIPS_ARGUMENT_REQUIRED_OUTPUT,
G_STRUCT_OFFSET( VipsGlobalbalance, out ) );
VIPS_ARG_DOUBLE( class, "gamma", 5,
_( "gamma" ),
_( "Image gamma" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsGlobalbalance, gamma ),
0.00001, 10, 1.6 );
VIPS_ARG_BOOL( class, "int_output", 7,
_( "Int output" ),
_( "Integer output" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsGlobalbalance, int_output ),
FALSE );
}
static void
vips_globalbalance_init( VipsGlobalbalance *globalbalance )
{
globalbalance->gamma = 1.6;
}
/**
* im_global_balance:
* vips_globalbalance:
* @in: mosaic to rebuild
* @out: output image
* @gamma: gamma of source images
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* im_global_balance() can be used to remove contrast differences in
* @gamma: gamma of source images
* @int_output: %TRUE for integer image output
*
* vips_globalbalance() can be used to remove contrast differences in
* an assembled mosaic.
*
* It reads the History field attached to @in and builds a list of the source
@ -1726,56 +1821,28 @@ transformf( JoinNode *node, double *gamma )
* 1.0 will stop this.
*
* Each of the source images is transformed with the appropriate correction
* factor, then the mosaic is reassembled. @out always has the same #BandFmt
* as @in. Use im_global_balancef() to get float output and avoid clipping.
* factor, then the mosaic is reassembled. @out is #VIPS_FORMAT_FLOAT, but
* if @int_output is set, the output image is the same format as the input
* images.
*
* There are some conditions that must be met before this operation can work:
* the source images must all be present under the filenames recorded in the
* history on @in, and the mosaic must have been built using only operations in
* this package.
*
* See also: im_global_balancef(), im_remosaic().
* See also: vips_remosaic().
*
* Returns: 0 on success, -1 on error
*/
int
im_global_balance( IMAGE *in, IMAGE *out, double gamma )
int
vips_globalbalance( VipsImage *in, VipsImage **out, ... )
{
SymbolTable *st;
va_list ap;
int result;
if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) ||
analyse_mosaic( st, in ) ||
find_factors( st, gamma ) ||
im__build_mosaic( st, out, (transform_fn) transform, &gamma ) )
return( -1 );
va_start( ap, out );
result = vips_call_split( "globalbalance", ap, in, out );
va_end( ap );
return( 0 );
}
/**
* im_global_balancef:
* @in: mosaic to rebuild
* @out: output image
* @gamma: gamma of source images
*
* Just as im_global_balance(), but the output image is always float. This
* stops overflow or underflow in the case of an extremely unbalanced image
* mosaic.
*
* See also: im_global_balance(), im_remosaic().
*
* Returns: 0 on success, -1 on error
*/
int
im_global_balancef( IMAGE *in, IMAGE *out, double gamma )
{
SymbolTable *st;
if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) ||
analyse_mosaic( st, in ) ||
find_factors( st, gamma ) ||
im__build_mosaic( st, out, (transform_fn) transformf, &gamma ) )
return( -1 );
return( 0 );
return( result );
}

View File

@ -58,14 +58,14 @@
*
* The mosaicing functions can be grouped into layers:
*
* The lowest level functions are im_correl(), im_lrmerge() and im_tbmerge().
* The lowest level functions are im_correl() and vips_merge().
* im_correl()
* searches a large image for a small sub-image, returning
* the position of the best sub-image match. im_lrmerge() and im_tbmerge()
* join two images together
* the position of the best sub-image match. vips_merge()
* joins two images together
* left-right or up-down with a smooth seam.
*
* Next, im_lrmosaic() and im_tbmosaic() use the
* Next, vips_mosaic() use the
* search function plus the two low-level merge operations to join two images
* given just an approximate overlap as a start point.
*
@ -76,7 +76,7 @@
* them to rotate and scale the right-hand or bottom image before starting to
* join.
*
* Finally, im_global_balance() can be used to remove contrast differences in
* Finally, vips_globalbalance() can be used to remove contrast differences in
* a mosaic
* which has been assembled with these functions. It takes the mosaic apart,
* measures image contrast differences along the seams, finds a set of
@ -98,8 +98,10 @@ vips_mosaicing_operation_init( void )
extern int vips_merge_get_type( void );
extern int vips_mosaic_get_type( void );
extern int vips_match_get_type( void );
extern int vips_globalbalance_get_type( void );
vips_merge_get_type();
vips_mosaic_get_type();
vips_match_get_type();
vips_globalbalance_get_type();
}