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
|
- kick load operations from cache on read error, thanks gaillard
|
||||||
- fix return from C++ assignment operator overloads (+=, -= etc)
|
- fix return from C++ assignment operator overloads (+=, -= etc)
|
||||||
- add @max_slope to vips_local_hist() to implement CLAHE, thanks hunter-87
|
- 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
|
8/12/16 started 8.4.5
|
||||||
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
* - redo as a class
|
* - redo as a class
|
||||||
* 8/11/14
|
* 8/11/14
|
||||||
* - use g_random_double()
|
* - 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 mean;
|
||||||
double sigma;
|
double sigma;
|
||||||
|
|
||||||
|
/* Per-image seed.
|
||||||
|
*/
|
||||||
|
guint32 seed;
|
||||||
} VipsGaussnoise;
|
} VipsGaussnoise;
|
||||||
|
|
||||||
typedef VipsCreateClass VipsGaussnoiseClass;
|
typedef VipsCreateClass VipsGaussnoiseClass;
|
||||||
@ -93,12 +100,19 @@ vips_gaussnoise_gen( VipsRegion *or, void *seq, void *a, void *b,
|
|||||||
int x;
|
int x;
|
||||||
|
|
||||||
for( x = 0; x < sz; x++ ) {
|
for( x = 0; x < sz; x++ ) {
|
||||||
|
guint32 seed;
|
||||||
double sum;
|
double sum;
|
||||||
int i;
|
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;
|
sum = 0.0;
|
||||||
for( i = 0; i < 12; i++ )
|
for( i = 0; i < 12; i++ ) {
|
||||||
sum += g_random_double();
|
seed = vips__random( seed );
|
||||||
|
sum += (double) seed / UINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
q[x] = (sum - 6.0) * gaussnoise->sigma +
|
q[x] = (sum - 6.0) * gaussnoise->sigma +
|
||||||
gaussnoise->mean;
|
gaussnoise->mean;
|
||||||
@ -124,6 +138,11 @@ vips_gaussnoise_build( VipsObject *object )
|
|||||||
vips_image_pipelinev( create->out,
|
vips_image_pipelinev( create->out,
|
||||||
VIPS_DEMAND_STYLE_ANY, NULL );
|
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,
|
if( vips_image_generate( create->out,
|
||||||
NULL, vips_gaussnoise_gen, NULL, gaussnoise, NULL ) )
|
NULL, vips_gaussnoise_gen, NULL, gaussnoise, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -92,21 +92,6 @@ typedef struct _Sequence {
|
|||||||
|
|
||||||
} 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.
|
/* Generate a 3 x 3 grid of cells around a point.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -135,13 +120,12 @@ vips_perlin_create_cells( VipsPerlin *perlin,
|
|||||||
|
|
||||||
if( cy >= perlin->cells_down )
|
if( cy >= perlin->cells_down )
|
||||||
cy = 0;
|
cy = 0;
|
||||||
seed = vips_perlin_seed_add( seed, cy );
|
seed = vips__random_add( seed, cy );
|
||||||
|
|
||||||
if( cx >= perlin->cells_across )
|
if( cx >= perlin->cells_across )
|
||||||
cx = 0;
|
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;
|
angle = (seed ^ (seed >> 8) ^ (seed >> 16)) & 0xff;
|
||||||
|
|
||||||
gx[ci] = vips_perlin_cos[angle];
|
gx[ci] = vips_perlin_cos[angle];
|
||||||
|
@ -107,21 +107,6 @@ typedef struct _Sequence {
|
|||||||
|
|
||||||
} 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.
|
/* Generate a 3 x 3 grid of cells around a point.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -154,7 +139,7 @@ vips_worley_create_cells( VipsWorley *worley,
|
|||||||
value = worley->cells_across - 1;
|
value = worley->cells_across - 1;
|
||||||
else
|
else
|
||||||
value = cell->cell_x;
|
value = cell->cell_x;
|
||||||
seed = vips_worley_seed_add( seed, value );
|
seed = vips__random_add( seed, value );
|
||||||
|
|
||||||
if( cell->cell_y >= worley->cells_down )
|
if( cell->cell_y >= worley->cells_down )
|
||||||
value = 0;
|
value = 0;
|
||||||
@ -162,20 +147,19 @@ vips_worley_create_cells( VipsWorley *worley,
|
|||||||
value = worley->cells_down - 1;
|
value = worley->cells_down - 1;
|
||||||
else
|
else
|
||||||
value = cell->cell_y;
|
value = cell->cell_y;
|
||||||
seed = vips_worley_seed_add( seed, value );
|
seed = vips__random_add( seed, value );
|
||||||
|
|
||||||
/* [1, MAX_FEATURES)
|
/* [1, MAX_FEATURES)
|
||||||
*/
|
*/
|
||||||
seed = vips_worley_random( seed );
|
|
||||||
cell->n_features = (seed % (MAX_FEATURES - 1)) + 1;
|
cell->n_features = (seed % (MAX_FEATURES - 1)) + 1;
|
||||||
|
|
||||||
for( j = 0; j < cell->n_features; j++ ) {
|
for( j = 0; j < cell->n_features; j++ ) {
|
||||||
seed = vips_worley_random( seed );
|
seed = vips__random( seed );
|
||||||
cell->feature_x[j] =
|
cell->feature_x[j] =
|
||||||
cell->cell_x * worley->cell_size +
|
cell->cell_x * worley->cell_size +
|
||||||
seed % worley->cell_size;
|
seed % worley->cell_size;
|
||||||
|
|
||||||
seed = vips_worley_random( seed );
|
seed = vips__random( seed );
|
||||||
cell->feature_y[j] =
|
cell->feature_y[j] =
|
||||||
cell->cell_y * worley->cell_size +
|
cell->cell_y * worley->cell_size +
|
||||||
seed % 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 );
|
char *vips_realpath( const char *path );
|
||||||
|
|
||||||
|
guint32 vips__random( guint32 seed );
|
||||||
|
guint32 vips__random_add( guint32 seed, int value );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
@ -1912,3 +1912,20 @@ vips_realpath( const char *path )
|
|||||||
|
|
||||||
return( real );
|
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