sort max/min results by y and x coordinate

previously the list of maxima or minima found by max/min were in found
order, so essentially random

they now sort equal values by y then x coordinate, so the results are
consistent between runs, provided there are fewer maxima / minima than
are being tracked
This commit is contained in:
John Cupitt 2017-01-24 14:25:15 +00:00
parent fb544e3f25
commit 7136053451
4 changed files with 32 additions and 8 deletions

View File

@ -29,6 +29,7 @@
- fix return from C++ assignment operator overloads (+=, -= etc)
- add @max_slope to vips_hist_local() to implement CLAHE, thanks hunter-87
- vips_gaussnoise() pixels are reproducible on recalc, thanks MvGulik
- max/min sort values by y and x coordinate
8/12/16 started 8.4.5
- allow libgsf-1.14.26 to help centos, thanks tdiprima

View File

@ -23,6 +23,8 @@
* - allow +/- INFINITY as a result
* 4/12/12
* - track and return top n values
* 24/1/17
* - sort equal values by y then x to make order more consistent
*/
/*
@ -143,10 +145,20 @@ vips_values_add( VipsValues *values, double v, int x, int y )
/* Find insertion point.
*/
for( i = 0; i < values->n; i++ )
if( v <= values->value[i] )
for( i = 0; i < values->n; i++ ) {
if( v < values->value[i] )
break;
if( v == values->value[i] ) {
if( y < values->y_pos[i] )
break;
if( y == values->y_pos[i] )
if( x <= values->x_pos[i] )
break;
}
}
/* Array full?
*/
if( values->n == values->size ) {
@ -498,6 +510,7 @@ vips_max_init( VipsMax *max )
* By default it finds the single largest value. If @size is set >1, it will
* find the @size largest values. It will stop searching early if has found
* enough values.
* Equal values will be sorted by y then x.
*
* It operates on all
* bands of the input image: use vips_stats() if you need to find an
@ -511,8 +524,7 @@ vips_max_init( VipsMax *max )
* largest to smallest.
*
* If there are more than @size maxima, the maxima returned will be a random
* selection of the maxima in the image. Equal maxima will be returned in a
* random order.
* selection of the maxima in the image.
*
* See also: vips_min(), vips_stats().
*

View File

@ -145,10 +145,20 @@ vips_values_add( VipsValues *values, double v, int x, int y )
/* Find insertion point.
*/
for( i = 0; i < values->n; i++ )
if( v >= values->value[i] )
for( i = 0; i < values->n; i++ ) {
if( v > values->value[i] )
break;
if( v == values->value[i] ) {
if( y < values->y_pos[i] )
break;
if( y == values->y_pos[i] )
if( x <= values->x_pos[i] )
break;
}
}
/* Array full?
*/
if( values->n == values->size ) {
@ -501,6 +511,7 @@ vips_min_init( VipsMin *min )
* By default it finds the single smallest value. If @size is set >1, it will
* find the @size smallest values. It will stop searching early if has found
* enough values.
* Equal values will be sorted by y then x.
*
* It operates on all
* bands of the input image: use vips_stats() if you need to find an
@ -515,8 +526,7 @@ vips_min_init( VipsMin *min )
* smallest to largest.
*
* If there are more than @size minima, the minima returned will be a random
* selection of the minima in the image. Equal minima will be returned in a
* random order.
* selection of the minima in the image.
*
* See also: vips_min(), vips_stats().
*

View File

@ -168,6 +168,7 @@ vips_statistic_class_init( VipsStatisticClass *class )
_( "Input image" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsStatistic, in ) );
}
static void