From 330ebf3cd7114afd6bc634b450bea20d73fd864f Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 3 Mar 2022 21:10:20 +0100 Subject: [PATCH] Mosaicing fixes and improvements (#2705) * Fix segv in `vips_mosaic1` * Fix ref handling in `rotjoin_search` * Pass `oarea` to `vips_affine` as `VipsArrayInt` instead * Flip X/Y positions in `vips__coeff` * Fix `-Wunused-but-set-variable` warning * Deprecate unused mosaicing arguments * Remove a couple of stray header decls --- cplusplus/include/vips/VImage8.h | 1 - libvips/deprecated/mosaicing_dispatch.c | 24 ++++++++------------ libvips/deprecated/vips7compat.c | 2 -- libvips/include/vips/internal.h | 2 -- libvips/include/vips/vips7compat.h | 6 ----- libvips/mosaicing/global_balance.c | 10 ++++----- libvips/mosaicing/im_clinear.c | 3 +-- libvips/mosaicing/lrmosaic.c | 1 - libvips/mosaicing/match.c | 16 ++++++------- libvips/mosaicing/mosaic1.c | 30 ++++++++++++++++--------- libvips/mosaicing/tbmosaic.c | 1 - 11 files changed, 42 insertions(+), 54 deletions(-) diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index aff27543..e719143f 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -4363,7 +4363,6 @@ VImage mosaic( VImage sec, VipsDirection direction, int xref, int yref, int xsec * - **search** -- Search to improve tie-points, bool. * - **interpolate** -- Interpolate pixels with this, VInterpolate. * - **mblend** -- Maximum blend size, int. - * - **bandno** -- Band to search for features on, int. * * @param sec Secondary image. * @param direction Horizontal or vertical mosaic. diff --git a/libvips/deprecated/mosaicing_dispatch.c b/libvips/deprecated/mosaicing_dispatch.c index 9544f895..899e868d 100644 --- a/libvips/deprecated/mosaicing_dispatch.c +++ b/libvips/deprecated/mosaicing_dispatch.c @@ -83,7 +83,7 @@ static im_arg_desc mosaic_args[] = { IM_INPUT_INT( "ys" ), IM_INPUT_INT( "halfcorrelation" ), IM_INPUT_INT( "halfarea" ), - IM_INPUT_INT( "balancetype" ), + IM_INPUT_INT( "balancetype" ), // Deprecated IM_INPUT_INT( "mwidth" ) }; @@ -93,7 +93,7 @@ static im_arg_desc mosaic1_args[] = { IM_INPUT_IMAGE( "ref" ), IM_INPUT_IMAGE( "sec" ), IM_OUTPUT_IMAGE( "out" ), - IM_INPUT_INT( "bandno" ), + IM_INPUT_INT( "bandno" ), // Deprecated IM_INPUT_INT( "xr1" ), IM_INPUT_INT( "yr1" ), IM_INPUT_INT( "xs1" ), @@ -104,7 +104,7 @@ static im_arg_desc mosaic1_args[] = { IM_INPUT_INT( "ys2" ), IM_INPUT_INT( "halfcorrelation" ), IM_INPUT_INT( "halfarea" ), - IM_INPUT_INT( "balancetype" ), + IM_INPUT_INT( "balancetype" ), // Deprecated IM_INPUT_INT( "mwidth" ) }; @@ -120,14 +120,13 @@ lrmosaic_vec( im_object *argv ) int ys = *((int *) argv[7]); int halfcorrelation = *((int *) argv[8]); int halfarea = *((int *) argv[9]); - int balancetype = *((int *) argv[10]); int mwidth = *((int *) argv[11]); return( vips__lrmosaic( argv[0], argv[1], argv[2], bandno, xr, yr, xs, ys, halfcorrelation, halfarea, - balancetype, mwidth ) ); + mwidth ) ); } /* Call im_lrmosaic1 via arg vector. @@ -135,7 +134,6 @@ lrmosaic_vec( im_object *argv ) static int lrmosaic1_vec( im_object *argv ) { - int bandno = *((int *) argv[3]); int xr1 = *((int *) argv[4]); int yr1 = *((int *) argv[5]); int xs1 = *((int *) argv[6]); @@ -146,15 +144,14 @@ lrmosaic1_vec( im_object *argv ) int ys2 = *((int *) argv[11]); int halfcorrelation = *((int *) argv[12]); int halfarea = *((int *) argv[13]); - int balancetype = *((int *) argv[14]); int mwidth = *((int *) argv[15]); return( im_lrmosaic1( argv[0], argv[1], argv[2], - bandno, + 0, xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, halfcorrelation, halfarea, - balancetype, mwidth ) ); + 0, mwidth ) ); } /* Description of im_lrmosaic. @@ -254,14 +251,13 @@ tbmosaic_vec( im_object *argv ) int y2 = *((int *) argv[7]); int halfcorrelation = *((int *) argv[8]); int halfarea = *((int *) argv[9]); - int balancetype = *((int *) argv[10]); int mwidth = *((int *) argv[11]); return( vips__tbmosaic( argv[0], argv[1], argv[2], bandno, x1, y1, x2, y2, halfcorrelation, halfarea, - balancetype, mwidth ) ); + mwidth ) ); } /* Call im_tbmosaic1 via arg vector. @@ -269,7 +265,6 @@ tbmosaic_vec( im_object *argv ) static int tbmosaic1_vec( im_object *argv ) { - int bandno = *((int *) argv[3]); int xr1 = *((int *) argv[4]); int yr1 = *((int *) argv[5]); int xs1 = *((int *) argv[6]); @@ -280,15 +275,14 @@ tbmosaic1_vec( im_object *argv ) int ys2 = *((int *) argv[11]); int halfcorrelation = *((int *) argv[12]); int halfarea = *((int *) argv[13]); - int balancetype = *((int *) argv[14]); int mwidth = *((int *) argv[15]); return( im_tbmosaic1( argv[0], argv[1], argv[2], - bandno, + 0, xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, halfcorrelation, halfarea, - balancetype, mwidth ) ); + 0, mwidth ) ); } /* Call im__find_tboverlap via arg vector. diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 2b0f6c8a..1c0989f9 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -5349,7 +5349,6 @@ im_lrmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out, if( vips_mosaic1( ref, sec, &x, VIPS_DIRECTION_HORIZONTAL, xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, "search", TRUE, - "bandno", bandno, "hwindow", hwindowsize, "harea", hsearchsize, "mblend", mwidth, @@ -5404,7 +5403,6 @@ im_tbmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out, if( vips_mosaic1( ref, sec, &x, VIPS_DIRECTION_VERTICAL, xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, "search", TRUE, - "bandno", bandno, "hwindow", hwindowsize, "harea", hsearchsize, "mblend", mwidth, diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 7ca1a8bf..bcb3a790 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -306,14 +306,12 @@ int vips__lrmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out, int bandno, int xref, int yref, int xsec, int ysec, int hwindowsize, int hsearchsize, - int balancetype, int mwidth ); int vips__tbmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out, int bandno, int xref, int yref, int xsec, int ysec, int hwindowsize, int hsearchsize, - int balancetype, int mwidth ); int vips__correl( VipsImage *ref, VipsImage *sec, diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 144c4d43..1a633948 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -1165,12 +1165,6 @@ int vips__find_tboverlap( VipsImage *ref_in, VipsImage *sec_in, VipsImage *out, int halfcorrelation, int halfarea, int *dx0, int *dy0, double *scale1, double *angle1, double *dx1, double *dy1 ); -int im__find_best_contrast( VipsImage *image, - int xpos, int ypos, int xsize, int ysize, - int xarray[], int yarray[], int cont[], - int nbest, int hcorsize ); -int im__balance( VipsImage *ref, VipsImage *sec, VipsImage *out, - VipsImage **ref_out, VipsImage **sec_out, int dx, int dy, int balancetype ); void imb_LCh2Lab( float *, float *, int ); diff --git a/libvips/mosaicing/global_balance.c b/libvips/mosaicing/global_balance.c index 77ed6c7a..b3a8c37f 100644 --- a/libvips/mosaicing/global_balance.c +++ b/libvips/mosaicing/global_balance.c @@ -1633,12 +1633,12 @@ vips__affinei( VipsImage *in, VipsImage *out, VipsTransformation *trn ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( out ), 2 ); - VipsArea *oarea; + VipsArrayInt *oarea; gboolean repack; - oarea = VIPS_AREA( vips_array_int_newv( 4, + oarea = vips_array_int_newv( 4, trn->oarea.left, trn->oarea.top, - trn->oarea.width, trn->oarea.height ) ); + trn->oarea.width, trn->oarea.height ); /* vips7 affine would repack labq and im_benchmark() depends upon * this. @@ -1651,10 +1651,10 @@ vips__affinei( VipsImage *in, VipsImage *out, VipsTransformation *trn ) "odx", trn->odx, "ody", trn->ody, NULL ) ) { - vips_area_unref( oarea ); + vips_area_unref( VIPS_AREA( oarea ) ); return( -1 ); } - vips_area_unref( oarea ); + vips_area_unref( VIPS_AREA( oarea ) ); in = t[0]; if( repack ) { diff --git a/libvips/mosaicing/im_clinear.c b/libvips/mosaicing/im_clinear.c index 61025fcd..c8a725b4 100644 --- a/libvips/mosaicing/im_clinear.c +++ b/libvips/mosaicing/im_clinear.c @@ -69,7 +69,7 @@ vips__clinear( TiePoints *points ) VipsImage *mat, *matinv; double *g; double value; - double sx1 = 0.0, sx1x1 = 0.0, sy1 = 0.0, sy1y1 = 0.0, sx1y1 = 0.0; + double sx1 = 0.0, sx1x1 = 0.0, sy1 = 0.0, sy1y1 = 0.0; double sx2x1 = 0.0, sx2y1 = 0.0, sx2 = 0.0, sy2 = 0.0, sy2y1 = 0.0, sy2x1 = 0.0; int i, j; @@ -99,7 +99,6 @@ vips__clinear( TiePoints *points ) sx1x1 += xref[i] * xref[i]; sy1 += yref[i]; sy1y1 += yref[i] * yref[i]; - sx1y1 += xref[i] * yref[i]; sx2x1 += xsec[i] * xref[i]; sx2y1 += xsec[i] * yref[i]; sy2y1 += ysec[i] * yref[i]; diff --git a/libvips/mosaicing/lrmosaic.c b/libvips/mosaicing/lrmosaic.c index 835a2cfc..abec4acf 100644 --- a/libvips/mosaicing/lrmosaic.c +++ b/libvips/mosaicing/lrmosaic.c @@ -246,7 +246,6 @@ vips__lrmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out, int bandno, int xref, int yref, int xsec, int ysec, int hwindowsize, int hsearchsize, - int balancetype, int mwidth ) { int dx0, dy0; diff --git a/libvips/mosaicing/match.c b/libvips/mosaicing/match.c index 773eb225..abb6d59a 100644 --- a/libvips/mosaicing/match.c +++ b/libvips/mosaicing/match.c @@ -66,14 +66,14 @@ vips__coeff( int xr1, int yr1, int xs1, int ys1, return( -1 ); } - *a = *VIPS_MATRIX( t[1], 0, 0 ) * xr1 + *VIPS_MATRIX( t[1], 0, 1 ) * yr1 + - *VIPS_MATRIX( t[1], 0, 2 ) * xr2 + *VIPS_MATRIX( t[1], 0, 3 ) * yr2; - *b = *VIPS_MATRIX( t[1], 1, 0 ) * xr1 + *VIPS_MATRIX( t[1], 1, 1 ) * yr1 + - *VIPS_MATRIX( t[1], 1, 2 ) * xr2 + *VIPS_MATRIX( t[1], 1, 3 ) * yr2; - *dx= *VIPS_MATRIX( t[1], 2, 0 ) * xr1 + *VIPS_MATRIX( t[1], 2, 1 ) * yr1 + - *VIPS_MATRIX( t[1], 2, 2 ) * xr2 + *VIPS_MATRIX( t[1], 2, 3 ) * yr2; - *dy= *VIPS_MATRIX( t[1], 3, 0 ) * xr1 + *VIPS_MATRIX( t[1], 3, 1 ) * yr1 + - *VIPS_MATRIX( t[1], 3, 2 ) * xr2 + *VIPS_MATRIX( t[1], 3, 3 ) * yr2; + *a = *VIPS_MATRIX( t[1], 0, 0 ) * xr1 + *VIPS_MATRIX( t[1], 1, 0 ) * yr1 + + *VIPS_MATRIX( t[1], 2, 0 ) * xr2 + *VIPS_MATRIX( t[1], 3, 0 ) * yr2; + *b = *VIPS_MATRIX( t[1], 0, 1 ) * xr1 + *VIPS_MATRIX( t[1], 1, 1 ) * yr1 + + *VIPS_MATRIX( t[1], 2, 1 ) * xr2 + *VIPS_MATRIX( t[1], 3, 1 ) * yr2; + *dx = *VIPS_MATRIX( t[1], 0, 2 ) * xr1 + *VIPS_MATRIX( t[1], 1, 2 ) * yr1 + + *VIPS_MATRIX( t[1], 2, 2 ) * xr2 + *VIPS_MATRIX( t[1], 3, 2 ) * yr2; + *dy = *VIPS_MATRIX( t[1], 0, 3 ) * xr1 + *VIPS_MATRIX( t[1], 1, 3 ) * yr1 + + *VIPS_MATRIX( t[1], 2, 3 ) * xr2 + *VIPS_MATRIX( t[1], 3, 3 ) * yr2; g_object_unref( t[0] ); g_object_unref( t[1] ); diff --git a/libvips/mosaicing/mosaic1.c b/libvips/mosaicing/mosaic1.c index 70149c27..70f960e7 100644 --- a/libvips/mosaicing/mosaic1.c +++ b/libvips/mosaicing/mosaic1.c @@ -114,6 +114,8 @@ vips__lrmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out, VipsBuf buf; char text[1024]; + t[0] = vips_image_new(); + /* Scale, rotate and displace sec. */ if( apply_similarity( &trn, sec, t[0], a, b, dx, dy ) ) @@ -160,6 +162,8 @@ vips__tbmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out, VipsBuf buf; char text[1024]; + t[0] = vips_image_new(); + /* Scale, rotate and displace sec. */ if( apply_similarity( &trn, sec, t[0], a, b, dx, dy ) ) @@ -222,11 +226,9 @@ rotjoin( VipsImage *ref, VipsImage *sec, VipsImage *out, joinfn jfn, */ static int rotjoin_search( VipsImage *ref, VipsImage *sec, VipsImage *out, joinfn jfn, - int bandno, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int halfcorrelation, int halfarea, - int balancetype, int mwidth ) { VipsTransformation trn; @@ -250,14 +252,20 @@ rotjoin_search( VipsImage *ref, VipsImage *sec, VipsImage *out, joinfn jfn, if( vips_LabQ2LabS( ref, &t[0], NULL ) ) return( -1 ); } - else + else { t[0] = ref; + g_object_ref( t[0] ); + } if( sec->Coding == VIPS_CODING_LABQ ) { if( vips_LabQ2LabS( sec, &t[1], NULL ) ) return( -1 ); } - else + else { t[1] = sec; + g_object_ref( t[1] ); + } + + t[2] = vips_image_new(); /* Solve to get scale + rot + disp. */ @@ -329,7 +337,6 @@ old_lrmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, int halfcorrelation, int halfarea, - int balancetype, int mwidth ) { VipsTransformation trn1, trn2; @@ -346,6 +353,8 @@ old_lrmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out, vips_object_local_array( VIPS_OBJECT( out ), 2 ); VipsImage *dummy; + t[0] = vips_image_new(); + /* Solve to get scale + rot + disp. */ if( vips__coeff( xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, @@ -382,6 +391,8 @@ old_lrmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out, printf( "final: a = %g, b = %g, dx = %g, dy = %g\n", af, bf, dxf, dyf ); + t[1] = vips_image_new(); + /* Scale and rotate final. */ if( apply_similarity( &trn2, sec, t[1], af, bf, dxf, dyf ) ) @@ -394,7 +405,7 @@ old_lrmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out, /* And join to ref. */ - if( vips_merge( ref, t[1], out, VIPS_DIRECtION_HORIZONTAL, + if( vips_merge( ref, t[1], out, VIPS_DIRECTION_HORIZONTAL, -trn2.area.left, -trn2.area.top, mwidth ) ) return( -1 ); @@ -451,11 +462,9 @@ vips_mosaic1_build( VipsObject *object ) if( mosaic1->search ) { if( rotjoin_search( mosaic1->ref, mosaic1->sec, mosaic1->out, jfn, - mosaic1->bandno, mosaic1->xr1, mosaic1->yr1, mosaic1->xs1, mosaic1->ys1, mosaic1->xr2, mosaic1->yr2, mosaic1->xs2, mosaic1->ys2, - mosaic1->hwindow, mosaic1->harea, - 0, + mosaic1->hwindow, mosaic1->harea, mosaic1->mblend ) ) return( -1 ); } @@ -602,7 +611,7 @@ vips_mosaic1_class_init( VipsMosaic1Class *class ) VIPS_ARG_INT( class, "bandno", 18, _( "Search band" ), _( "Band to search for features on" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, G_STRUCT_OFFSET( VipsMosaic1, bandno ), 0, 10000, 0 ); @@ -639,7 +648,6 @@ vips_mosaic1_init( VipsMosaic1 *mosaic1 ) * * @harea: half search size * * @interpolate: interpolate pixels with this * * @mblend: maximum blend size - * * @bandno: band to search for features * * This operation joins two images top-bottom (with @sec on the right) * or left-right (with @sec at the bottom) diff --git a/libvips/mosaicing/tbmosaic.c b/libvips/mosaicing/tbmosaic.c index 89ddf299..62322ad5 100644 --- a/libvips/mosaicing/tbmosaic.c +++ b/libvips/mosaicing/tbmosaic.c @@ -217,7 +217,6 @@ vips__tbmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out, int bandno, int xref, int yref, int xsec, int ysec, int hwindowsize, int hsearchsize, - int balancetype, int mwidth ) { int dx0, dy0;