make vips_gaussnoise() pixels reproducible
previously, pixel values were regenerated on every calculation, so they changed on recomputation pixel values are now generated from the pixel (x, y) coordinate plus a per-call seed thanks MvGulik, see https://github.com/jcupitt/nip2/issues/60 https://github.com/jcupitt/libvips/issues/583
This commit is contained in:
parent
c963678549
commit
36761bcfd7
@ -28,6 +28,7 @@
|
||||
- kick load operations from cache on read error, thanks gaillard
|
||||
- fix return from C++ assignment operator overloads (+=, -= etc)
|
||||
- add @max_slope to vips_local_hist() to implement CLAHE, thanks hunter-87
|
||||
- vips_gaussnoise() pixels are reproducible on recalc, thanks MvGulik
|
||||
|
||||
8/12/16 started 8.4.5
|
||||
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
||||
|
@ -22,6 +22,10 @@
|
||||
* - redo as a class
|
||||
* 8/11/14
|
||||
* - use g_random_double()
|
||||
* 24/1/17
|
||||
* - use g_random_double() once per image, use vips__random() for pixel
|
||||
* values from (x, y) position ... makes pixels reproducible on
|
||||
* recalculation
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -71,6 +75,9 @@ typedef struct _VipsGaussnoise {
|
||||
double mean;
|
||||
double sigma;
|
||||
|
||||
/* Per-image seed.
|
||||
*/
|
||||
guint32 seed;
|
||||
} VipsGaussnoise;
|
||||
|
||||
typedef VipsCreateClass VipsGaussnoiseClass;
|
||||
@ -93,12 +100,19 @@ vips_gaussnoise_gen( VipsRegion *or, void *seq, void *a, void *b,
|
||||
int x;
|
||||
|
||||
for( x = 0; x < sz; x++ ) {
|
||||
guint32 seed;
|
||||
double sum;
|
||||
int i;
|
||||
|
||||
seed = gaussnoise->seed;
|
||||
seed = vips__random_add( seed, or->valid.left + x );
|
||||
seed = vips__random_add( seed, or->valid.top + y );
|
||||
|
||||
sum = 0.0;
|
||||
for( i = 0; i < 12; i++ )
|
||||
sum += g_random_double();
|
||||
for( i = 0; i < 12; i++ ) {
|
||||
seed = vips__random( seed );
|
||||
sum += (double) seed / UINT_MAX;
|
||||
}
|
||||
|
||||
q[x] = (sum - 6.0) * gaussnoise->sigma +
|
||||
gaussnoise->mean;
|
||||
@ -124,6 +138,11 @@ vips_gaussnoise_build( VipsObject *object )
|
||||
vips_image_pipelinev( create->out,
|
||||
VIPS_DEMAND_STYLE_ANY, NULL );
|
||||
|
||||
/* The seed for this image. Each pixel is seeded by this plus the (x,
|
||||
* y) coordinate.
|
||||
*/
|
||||
gaussnoise->seed = UINT_MAX * g_random_double();
|
||||
|
||||
if( vips_image_generate( create->out,
|
||||
NULL, vips_gaussnoise_gen, NULL, gaussnoise, NULL ) )
|
||||
return( -1 );
|
||||
|
@ -92,21 +92,6 @@ typedef struct _Sequence {
|
||||
|
||||
} Sequence;
|
||||
|
||||
/* A very simple random number generator. See:
|
||||
* http://isthe.com/chongo/tech/comp/fnv/#FNV-source
|
||||
*/
|
||||
static guint32
|
||||
vips_perlin_random( guint32 seed )
|
||||
{
|
||||
return( 1103515245u * seed + 12345 );
|
||||
}
|
||||
|
||||
static guint32
|
||||
vips_perlin_seed_add( guint32 seed, int value )
|
||||
{
|
||||
return( ((2166136261u ^ seed) * 16777619u) ^ value );
|
||||
}
|
||||
|
||||
/* Generate a 3 x 3 grid of cells around a point.
|
||||
*/
|
||||
static void
|
||||
@ -135,13 +120,12 @@ vips_perlin_create_cells( VipsPerlin *perlin,
|
||||
|
||||
if( cy >= perlin->cells_down )
|
||||
cy = 0;
|
||||
seed = vips_perlin_seed_add( seed, cy );
|
||||
seed = vips__random_add( seed, cy );
|
||||
|
||||
if( cx >= perlin->cells_across )
|
||||
cx = 0;
|
||||
seed = vips_perlin_seed_add( seed, cx );
|
||||
seed = vips__random_add( seed, cx );
|
||||
|
||||
seed = vips_perlin_random( seed );
|
||||
angle = (seed ^ (seed >> 8) ^ (seed >> 16)) & 0xff;
|
||||
|
||||
gx[ci] = vips_perlin_cos[angle];
|
||||
|
@ -107,21 +107,6 @@ typedef struct _Sequence {
|
||||
|
||||
} Sequence;
|
||||
|
||||
/* A very simple random number generator. See:
|
||||
* http://isthe.com/chongo/tech/comp/fnv/#FNV-source
|
||||
*/
|
||||
static guint32
|
||||
vips_worley_random( guint32 seed )
|
||||
{
|
||||
return( 1103515245u * seed + 12345 );
|
||||
}
|
||||
|
||||
static guint32
|
||||
vips_worley_seed_add( guint32 seed, int value )
|
||||
{
|
||||
return( ((2166136261u ^ seed) * 16777619u) ^ value );
|
||||
}
|
||||
|
||||
/* Generate a 3 x 3 grid of cells around a point.
|
||||
*/
|
||||
static void
|
||||
@ -154,7 +139,7 @@ vips_worley_create_cells( VipsWorley *worley,
|
||||
value = worley->cells_across - 1;
|
||||
else
|
||||
value = cell->cell_x;
|
||||
seed = vips_worley_seed_add( seed, value );
|
||||
seed = vips__random_add( seed, value );
|
||||
|
||||
if( cell->cell_y >= worley->cells_down )
|
||||
value = 0;
|
||||
@ -162,20 +147,19 @@ vips_worley_create_cells( VipsWorley *worley,
|
||||
value = worley->cells_down - 1;
|
||||
else
|
||||
value = cell->cell_y;
|
||||
seed = vips_worley_seed_add( seed, value );
|
||||
seed = vips__random_add( seed, value );
|
||||
|
||||
/* [1, MAX_FEATURES)
|
||||
*/
|
||||
seed = vips_worley_random( seed );
|
||||
cell->n_features = (seed % (MAX_FEATURES - 1)) + 1;
|
||||
|
||||
for( j = 0; j < cell->n_features; j++ ) {
|
||||
seed = vips_worley_random( seed );
|
||||
seed = vips__random( seed );
|
||||
cell->feature_x[j] =
|
||||
cell->cell_x * worley->cell_size +
|
||||
seed % worley->cell_size;
|
||||
|
||||
seed = vips_worley_random( seed );
|
||||
seed = vips__random( seed );
|
||||
cell->feature_y[j] =
|
||||
cell->cell_y * worley->cell_size +
|
||||
seed % worley->cell_size;
|
||||
|
@ -328,6 +328,9 @@ void vips__change_suffix( const char *name, char *out, int mx,
|
||||
|
||||
char *vips_realpath( const char *path );
|
||||
|
||||
guint32 vips__random( guint32 seed );
|
||||
guint32 vips__random_add( guint32 seed, int value );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
@ -1912,3 +1912,20 @@ vips_realpath( const char *path )
|
||||
|
||||
return( real );
|
||||
}
|
||||
|
||||
/* A very simple random number generator. See:
|
||||
* http://isthe.com/chongo/tech/comp/fnv/#FNV-source
|
||||
*/
|
||||
guint32
|
||||
vips__random( guint32 seed )
|
||||
{
|
||||
return( 1103515245u * seed + 12345 );
|
||||
}
|
||||
|
||||
guint32
|
||||
vips__random_add( guint32 seed, int value )
|
||||
{
|
||||
seed = ((2166136261u ^ seed) * 16777619u) ^ value;
|
||||
|
||||
return( vips__random( seed ) );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user