wrap im_match*() as a class
This commit is contained in:
parent
de409ecac8
commit
4f3b37ad04
@ -33,7 +33,7 @@
|
|||||||
- 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() redone as classes
|
- im_*merge(), im_*mosaic(), im_match*() 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
|
||||||
|
4
TODO
4
TODO
@ -1,3 +1,4 @@
|
|||||||
|
- test vips_match()
|
||||||
|
|
||||||
- quickly wrap the useful bits of mosaicing/
|
- quickly wrap the useful bits of mosaicing/
|
||||||
|
|
||||||
@ -5,10 +6,9 @@
|
|||||||
|
|
||||||
im_*merge() done
|
im_*merge() done
|
||||||
im_*mosaic() done
|
im_*mosaic() done
|
||||||
|
im_match_linear*() done
|
||||||
im_global_balancef()
|
im_global_balancef()
|
||||||
im_remosaic()
|
im_remosaic()
|
||||||
im_match_linear()
|
|
||||||
im_match_linear_search()
|
|
||||||
|
|
||||||
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
||||||
|
|
||||||
|
@ -44,6 +44,10 @@ 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 xr1, int yr1, int xs1, int ys1,
|
||||||
|
int xr2, int yr2, int xs2, int ys2, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,26 +90,6 @@ im__coeff( int xr1, int yr1, int xs1, int ys1,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* im_match_linear:
|
|
||||||
* @ref: reference image
|
|
||||||
* @sec: secondary image
|
|
||||||
* @out: output image
|
|
||||||
* @xr1: first reference tie-point
|
|
||||||
* @yr1: first reference tie-point
|
|
||||||
* @xs1: first secondary tie-point
|
|
||||||
* @ys1: first secondary tie-point
|
|
||||||
* @xr2: second reference tie-point
|
|
||||||
* @yr2: second reference tie-point
|
|
||||||
* @xs2: second secondary tie-point
|
|
||||||
* @ys2: second secondary tie-point
|
|
||||||
*
|
|
||||||
* Scale, rotate and translate @sec so that the tie-points line up.
|
|
||||||
*
|
|
||||||
* See also: im_match_linear_search().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
im_match_linear( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
im_match_linear( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
||||||
int xr1, int yr1, int xs1, int ys1,
|
int xr1, int yr1, int xs1, int ys1,
|
||||||
@ -140,35 +120,6 @@ im_match_linear( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* im_match_linear_search:
|
|
||||||
* @ref: reference image
|
|
||||||
* @sec: secondary image
|
|
||||||
* @out: output image
|
|
||||||
* @xr1: first reference tie-point
|
|
||||||
* @yr1: first reference tie-point
|
|
||||||
* @xs1: first secondary tie-point
|
|
||||||
* @ys1: first secondary tie-point
|
|
||||||
* @xr2: second reference tie-point
|
|
||||||
* @yr2: second reference tie-point
|
|
||||||
* @xs2: second secondary tie-point
|
|
||||||
* @ys2: second secondary tie-point
|
|
||||||
* @hwindowsize: half window size
|
|
||||||
* @hsearchsize: half search size
|
|
||||||
*
|
|
||||||
* Scale, rotate and translate @sec so that the tie-points line up.
|
|
||||||
*
|
|
||||||
* Before performing the transformation, the tie-points are improved by
|
|
||||||
* searching an area of @sec of size @hsearchsize for a
|
|
||||||
* match of size @hwindowsize to @ref.
|
|
||||||
*
|
|
||||||
* This function will only work well for small rotates and scales.
|
|
||||||
*
|
|
||||||
* See also: im_match_linear().
|
|
||||||
*
|
|
||||||
* Returns: 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
im_match_linear_search( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
im_match_linear_search( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
||||||
int xr1, int yr1, int xs1, int ys1,
|
int xr1, int yr1, int xs1, int ys1,
|
||||||
@ -189,3 +140,230 @@ im_match_linear_search( IMAGE *ref, IMAGE *sec, IMAGE *out,
|
|||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
VipsOperation parent_instance;
|
||||||
|
|
||||||
|
VipsImage *ref;
|
||||||
|
VipsImage *sec;
|
||||||
|
VipsImage *out;
|
||||||
|
int xr1;
|
||||||
|
int yr1;
|
||||||
|
int xs1;
|
||||||
|
int ys1;
|
||||||
|
int xr2;
|
||||||
|
int yr2;
|
||||||
|
int xs2;
|
||||||
|
int ys2;
|
||||||
|
int hwindow;
|
||||||
|
int harea;
|
||||||
|
gboolean search;
|
||||||
|
|
||||||
|
} VipsMatch;
|
||||||
|
|
||||||
|
typedef VipsOperationClass VipsMatchClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsMatch, vips_match, VIPS_TYPE_OPERATION );
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_match_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsMatch *match = (VipsMatch *) object;
|
||||||
|
|
||||||
|
g_object_set( match, "out", vips_image_new(), NULL );
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_match_parent_class )->build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( match->search ) {
|
||||||
|
int xs3, ys3;
|
||||||
|
int xs4, ys4;
|
||||||
|
double cor1, cor2;
|
||||||
|
|
||||||
|
if( im_correl( match->ref, match->sec,
|
||||||
|
match->xr1, match->yr1, match->xs1, match->ys1,
|
||||||
|
match->hwindow, match->harea,
|
||||||
|
&cor1, &xs3, &ys3 ) )
|
||||||
|
return( -1 );
|
||||||
|
if( im_correl( match->ref, match->sec,
|
||||||
|
match->xr2, match->yr2, match->xs2, match->ys2,
|
||||||
|
match->hwindow, match->harea,
|
||||||
|
&cor2, &xs4, &ys4 ) )
|
||||||
|
return( -1 );
|
||||||
|
match->xs1 = xs3;
|
||||||
|
match->ys1 = ys3;
|
||||||
|
match->xs2 = xs4;
|
||||||
|
match->ys2 = ys4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( im_match_linear( match->ref, match->sec, match->out,
|
||||||
|
match->xr1, match->yr1, match->xs1, match->ys1,
|
||||||
|
match->xr2, match->yr2, match->xs2, match->ys2 ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_match_class_init( VipsMatchClass *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 = "match";
|
||||||
|
object_class->description = _( "first-order match of two images" );
|
||||||
|
object_class->build = vips_match_build;
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( class, "ref", 1,
|
||||||
|
_( "Reference" ),
|
||||||
|
_( "Reference image" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, ref ) );
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( class, "sec", 2,
|
||||||
|
_( "Secondary" ),
|
||||||
|
_( "Secondary image" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, sec ) );
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( class, "out", 3,
|
||||||
|
_( "Output" ),
|
||||||
|
_( "Output image" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, out ) );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "xr1", 5,
|
||||||
|
_( "xr1" ),
|
||||||
|
_( "Position of first reference tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, xr1 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "yr1", 6,
|
||||||
|
_( "yr1" ),
|
||||||
|
_( "Position of first reference tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, yr1 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "xs1", 7,
|
||||||
|
_( "xs1" ),
|
||||||
|
_( "Position of first secondary tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, xs1 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "ys1", 8,
|
||||||
|
_( "ys1" ),
|
||||||
|
_( "Position of first secondary tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, ys1 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "xr2", 9,
|
||||||
|
_( "xr2" ),
|
||||||
|
_( "Position of second reference tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, xr2 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "yr2", 10,
|
||||||
|
_( "yr2" ),
|
||||||
|
_( "Position of second reference tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, yr2 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "xs2", 11,
|
||||||
|
_( "xs2" ),
|
||||||
|
_( "Position of second secondary tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, xs2 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "ys2", 12,
|
||||||
|
_( "ys2" ),
|
||||||
|
_( "Position of second secondary tie-point" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, ys2 ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "hwindow", 13,
|
||||||
|
_( "hwindow" ),
|
||||||
|
_( "Half window size" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, hwindow ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_INT( class, "harea", 14,
|
||||||
|
_( "harea" ),
|
||||||
|
_( "Half area size" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, harea ),
|
||||||
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "search", 13,
|
||||||
|
_( "search" ),
|
||||||
|
_( "Search to improve tie-points" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsMatch, search ),
|
||||||
|
FALSE );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_match_init( VipsMatch *match )
|
||||||
|
{
|
||||||
|
match->hwindow = 5;
|
||||||
|
match->harea = 15;
|
||||||
|
match->search = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_match:
|
||||||
|
* @ref: reference image
|
||||||
|
* @sec: secondary image
|
||||||
|
* @out: output image
|
||||||
|
* @xr1: first reference tie-point
|
||||||
|
* @yr1: first reference tie-point
|
||||||
|
* @xs1: first secondary tie-point
|
||||||
|
* @ys1: first secondary tie-point
|
||||||
|
* @xr2: second reference tie-point
|
||||||
|
* @yr2: second reference tie-point
|
||||||
|
* @xs2: second secondary tie-point
|
||||||
|
* @ys2: second secondary tie-point
|
||||||
|
*
|
||||||
|
* Optional arguments:
|
||||||
|
*
|
||||||
|
* @search: search to improve tie-points
|
||||||
|
* @hwindow: half window size
|
||||||
|
* @harea: half search size
|
||||||
|
*
|
||||||
|
* Scale, rotate and translate @sec so that the tie-points line up.
|
||||||
|
*
|
||||||
|
* If @search is %TRUE, before performing the transformation, the tie-points
|
||||||
|
* are improved by searching an area of @sec of size @harea for a
|
||||||
|
* match of size @hwindow to @ref.
|
||||||
|
*
|
||||||
|
* This function will only work well for small rotates and scales.
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
|
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, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start( ap, ys2 );
|
||||||
|
result = vips_call_split( "match", ap, ref, sec, out,
|
||||||
|
xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2 );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
@ -208,14 +208,14 @@ vips_mosaic_class_init( VipsMosaicClass *class )
|
|||||||
|
|
||||||
VIPS_ARG_INT( class, "xsec", 7,
|
VIPS_ARG_INT( class, "xsec", 7,
|
||||||
_( "xsec" ),
|
_( "xsec" ),
|
||||||
_( "Position of reference tie-point" ),
|
_( "Position of secondary tie-point" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsMosaic, xsec ),
|
G_STRUCT_OFFSET( VipsMosaic, xsec ),
|
||||||
0, 1000000000, 1 );
|
0, 1000000000, 1 );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "ysec", 8,
|
VIPS_ARG_INT( class, "ysec", 8,
|
||||||
_( "ysec" ),
|
_( "ysec" ),
|
||||||
_( "Position of reference tie-point" ),
|
_( "Position of secondary tie-point" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsMosaic, ysec ),
|
G_STRUCT_OFFSET( VipsMosaic, ysec ),
|
||||||
0, 1000000000, 1 );
|
0, 1000000000, 1 );
|
||||||
|
@ -97,7 +97,9 @@ vips_mosaicing_operation_init( void )
|
|||||||
{
|
{
|
||||||
extern int vips_merge_get_type( void );
|
extern int vips_merge_get_type( void );
|
||||||
extern int vips_mosaic_get_type( void );
|
extern int vips_mosaic_get_type( void );
|
||||||
|
extern int vips_match_get_type( void );
|
||||||
|
|
||||||
vips_merge_get_type();
|
vips_merge_get_type();
|
||||||
vips_mosaic_get_type();
|
vips_mosaic_get_type();
|
||||||
|
vips_match_get_type();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user