wrap im_remosaic() as a class

This commit is contained in:
John Cupitt 2014-05-27 15:18:19 +01:00
parent 781a7d4dc9
commit b8886fc209
6 changed files with 155 additions and 60 deletions

View File

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

15
TODO
View File

@ -1,13 +1,10 @@
- more mosaicing?
- quickly wrap the useful bits of mosaicing im_lrmerge1(), im_tbmerge1()
im_lrmosaic1(), im_tbmosaic1()
nip2 uses: im_correl
im_align_bands()
im_*merge() done im_maxpos_subpel()
im_*mosaic() done
im_match_linear*() done
im_global_balancef() done
im_remosaic()
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc. - can we use postbuild elsewhere? look at use of "preclose" / "written", etc.

View File

@ -5134,3 +5134,20 @@ im_global_balancef( IMAGE *in, IMAGE *out, double gamma )
return( 0 ); return( 0 );
} }
int
im_remosaic( IMAGE *in, IMAGE *out, const char *old_str, const char *new_str )
{
VipsImage *x;
if( vips_remosaic( in, &x, old_str, new_str, NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}

View File

@ -44,12 +44,17 @@ int vips_merge( VipsImage *ref, VipsImage *sec, VipsImage **out,
int vips_mosaic( VipsImage *ref, VipsImage *sec, VipsImage **out, int vips_mosaic( VipsImage *ref, VipsImage *sec, VipsImage **out,
VipsDirection direction, int xref, int yref, int xsec, int ysec, ... ) VipsDirection direction, int xref, int yref, int xsec, int ysec, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_match( VipsImage *ref, VipsImage *sec, VipsImage **out, int vips_match( VipsImage *ref, VipsImage *sec, VipsImage **out,
int xr1, int yr1, int xs1, int ys1, int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2, ... ) int xr2, int yr2, int xs2, int ys2, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_globalbalance( VipsImage *in, VipsImage **out, ... ) int vips_globalbalance( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel)); __attribute__((sentinel));
int vips_remosaic( VipsImage *in, VipsImage **out,
const char *old_str, const char *new_str, ... )
__attribute__((sentinel));
#include <vips/vips.h> #include <vips/vips.h>
@ -82,8 +87,6 @@ int im_correl( VipsImage *ref, VipsImage *sec,
int xref, int yref, int xsec, int ysec, int xref, int yref, int xsec, int ysec,
int hwindowsize, int hsearchsize, int hwindowsize, int hsearchsize,
double *correlation, int *x, int *y ); double *correlation, int *x, int *y );
int im_remosaic( VipsImage *in, VipsImage *out,
const char *old_str, const char *new_str );
int im_align_bands( VipsImage *in, VipsImage *out ); int im_align_bands( VipsImage *in, VipsImage *out );
int im_maxpos_subpel( VipsImage *in, double *x, double *y ); int im_maxpos_subpel( VipsImage *in, double *x, double *y );

View File

@ -1064,6 +1064,9 @@ int im_match_linear_search( VipsImage *ref, VipsImage *sec, VipsImage *out,
int im_global_balance( VipsImage *in, VipsImage *out, double gamma ); int im_global_balance( VipsImage *in, VipsImage *out, double gamma );
int im_global_balancef( VipsImage *in, VipsImage *out, double gamma ); int im_global_balancef( VipsImage *in, VipsImage *out, double gamma );
int im_remosaic( VipsImage *in, VipsImage *out,
const char *old_str, const char *new_str );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /*__cplusplus*/ #endif /*__cplusplus*/

View File

@ -56,15 +56,25 @@
#include "mosaic.h" #include "mosaic.h"
#include "global_balance.h" #include "global_balance.h"
typedef struct _RemosaicData { typedef struct {
const char *old_str; VipsOperation parent_instance;
const char *new_str;
VipsImage *in;
VipsImage *out;
char *old_str;
char *new_str;
int new_len; int new_len;
int old_len; int old_len;
} RemosaicData;
} VipsRemosaic;
typedef VipsOperationClass VipsRemosaicClass;
G_DEFINE_TYPE( VipsRemosaic, vips_remosaic, VIPS_TYPE_OPERATION );
static IMAGE * static IMAGE *
remosaic( JoinNode *node, RemosaicData *rd ) remosaic_fn( JoinNode *node, VipsRemosaic *remosaic )
{ {
SymbolTable *st = node->st; SymbolTable *st = node->st;
IMAGE *im = node->im; IMAGE *im = node->im;
@ -79,17 +89,17 @@ remosaic( JoinNode *node, RemosaicData *rd )
return( NULL ); return( NULL );
} }
/* Remove substring rd->old_str from in->filename, replace with /* Remove substring remosaic->old_str from in->filename, replace with
* rd->new_str. * remosaic->new_str.
*/ */
im_strncpy( filename, im->filename, FILENAME_MAX ); im_strncpy( filename, im->filename, FILENAME_MAX );
if( (p = im_strrstr( filename, rd->old_str )) ) { if( (p = im_strrstr( filename, remosaic->old_str )) ) {
int offset = p - &filename[0]; int offset = p - &filename[0];
im_strncpy( p, rd->new_str, FILENAME_MAX - offset ); im_strncpy( p, remosaic->new_str, FILENAME_MAX - offset );
im_strncpy( p + rd->new_len, im_strncpy( p + remosaic->new_len,
im->filename + offset + rd->old_len, im->filename + offset + remosaic->old_len,
FILENAME_MAX - offset - rd->new_len ); FILENAME_MAX - offset - remosaic->new_len );
} }
#ifdef DEBUG #ifdef DEBUG
@ -111,46 +121,111 @@ remosaic( JoinNode *node, RemosaicData *rd )
return( out ); return( out );
} }
/** static int
* im_remosaic: vips_remosaic_build( VipsObject *object )
* @in: mosaic to rebuild
* @out: output image
* @old_str: gamma of source images
* @new_str: gamma of source images
*
* im_remosaic() works rather as im_global_balance(). It takes apart the
* mosaiced image in and rebuilds it, substituting images.
*
* Unlike im_global_balance(), images are substituted based on their file
* names. The rightmost occurence of the string @old_str is swapped
* for @new_str, that file is opened, and that image substituted for
* the old image.
*
* It's convenient for multispectral images. You can mosaic one band, then
* use that mosaic as a template for mosaicing the others automatically.
*
* See also: im_lrmosaic(), im_global_balance().
*
* Returns: 0 on success, -1 on error
*/
int
im_remosaic( IMAGE *in, IMAGE *out, const char *old_str, const char *new_str )
{ {
SymbolTable *st; VipsRemosaic *remosaic = (VipsRemosaic *) object;
RemosaicData rd;
if( !(st = im__build_symtab( out, SYM_TAB_SIZE )) || SymbolTable *st;
im__parse_desc( st, in ) )
g_object_set( remosaic, "out", vips_image_new(), NULL );
if( VIPS_OBJECT_CLASS( vips_remosaic_parent_class )->
build( object ) )
return( -1 ); return( -1 );
/* Re-make mosaic. if( !(st = im__build_symtab( remosaic->out, SYM_TAB_SIZE )) ||
*/ im__parse_desc( st, remosaic->in ) )
rd.old_str = old_str; return( -1 );
rd.new_str = new_str;
rd.new_len = strlen( new_str ); remosaic->old_len = strlen( remosaic->old_str );
rd.old_len = strlen( old_str ); remosaic->new_len = strlen( remosaic->new_str );
if( im__build_mosaic( st, out, (transform_fn) remosaic, &rd ) ) if( im__build_mosaic( st, remosaic->out,
(transform_fn) remosaic_fn, remosaic ) )
return( -1 ); return( -1 );
return( 0 ); return( 0 );
} }
static void
vips_remosaic_class_init( VipsRemosaicClass *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 = "remosaic";
object_class->description = _( "global balance an image mosaic" );
object_class->build = vips_remosaic_build;
VIPS_ARG_IMAGE( class, "in", 1,
_( "Input" ),
_( "Input image" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsRemosaic, in ) );
VIPS_ARG_IMAGE( class, "out", 2,
_( "Output" ),
_( "Output image" ),
VIPS_ARGUMENT_REQUIRED_OUTPUT,
G_STRUCT_OFFSET( VipsRemosaic, out ) );
VIPS_ARG_STRING( class, "old_str", 5,
_( "old_str" ),
_( "Search for this string" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsRemosaic, old_str ),
"" );
VIPS_ARG_STRING( class, "new_str", 6,
_( "new_str" ),
_( "And swap for this string" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsRemosaic, new_str ),
"" );
}
static void
vips_remosaic_init( VipsRemosaic *remosaic )
{
}
/**
* vips_remosaic:
* @in: mosaic to rebuild
* @out: output image
* @old_str: gamma of source images
* @new_str: gamma of source images
* @...: %NULL-terminated list of optional named arguments
*
* vips_remosaic() works rather as vips_globalbalance(). It takes apart the
* mosaiced image @in and rebuilds it, substituting images.
*
* Unlike vips_globalbalance(), images are substituted based on their file
* names. The rightmost occurence of the string @old_str is swapped
* for @new_str, that file is opened, and that image substituted for
* the old image.
*
* It's convenient for multispectral images. You can mosaic one band, then
* use that mosaic as a template for mosaicing the others automatically.
*
* See also: vips_globalbalance().
*
* Returns: 0 on success, -1 on error
*/
int
vips_remosaic( VipsImage *in, VipsImage **out,
const char *old_str, const char *new_str, ... )
{
va_list ap;
int result;
va_start( ap, new_str );
result = vips_call_split( "remosaic", ap, in, out, old_str, new_str );
va_end( ap );
return( result );
}