VipsStats tracks minpos/maxpos

plus some small bugfixes
This commit is contained in:
John Cupitt 2011-11-08 21:50:19 +00:00
parent 1129d897ca
commit 62859facd4
2 changed files with 71 additions and 22 deletions

View File

@ -39,6 +39,7 @@
- switch SMALLTILE to 128, 512 was just too big
- oop mode "rd" was not always being used for images
- added ARRAY interpretation for images
- VipsStats tracks minpos/maxpos as well
12/10/11 started 7.26.6
- NOCACHE was not being set correctly on OS X causing performance

View File

@ -26,6 +26,7 @@
* - gtkdoc comment
* 7/11/11
* - redone as a class
* - track maxpos / minpos too
*/
/*
@ -54,6 +55,10 @@
*/
/*
*/
#define VIPS_DEBUG
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H*/
@ -126,8 +131,8 @@ vips_stats_build( VipsObject *object )
VipsStats *stats = (VipsStats *) object;
gint64 vals, pels;
double *row0;
int b;
double *row0, *row;
int b, y, i;
if( statistic->in ) {
int bands = vips_image_get_bands( statistic->in );
@ -149,19 +154,31 @@ vips_stats_build( VipsObject *object )
vals = pels * vips_image_get_bands( statistic->in );
row0 = ARY( stats->out, 0, 0 );
row = ARY( stats->out, 0, 1 );
for( i = 0; i < COL_LAST; i++ )
row0[i] = row[i];
row0[COL_MIN] = *ARY( stats->out, 0, COL_MIN );
row0[COL_MAX] = *ARY( stats->out, 0, COL_MAX );
row0[COL_SUM] = 0;
row0[COL_SUM2] = 0;
for( b = 1; b < vips_image_get_bands( statistic->in ); b++ ) {
row = ARY( stats->out, 0, b + 1 );
for( b = 0; b < vips_image_get_bands( statistic->in ); b++ ) {
double *row = ARY( stats->out, 0, b + 1 );
if( row[COL_MIN] < row0[COL_MIN] ) {
row0[COL_MIN] = row[COL_MIN];
row0[COL_XMIN] = row[COL_XMIN];
row0[COL_YMIN] = row[COL_YMIN];
}
if( row[COL_MAX] > row0[COL_MAX] ) {
row0[COL_MAX] = row[COL_MAX];
row0[COL_XMAX] = row[COL_XMAX];
row0[COL_YMAX] = row[COL_YMAX];
}
row0[COL_MIN] = VIPS_MIN( row0[COL_MIN], row[COL_MIN] );
row0[COL_MAX] = VIPS_MAX( row0[COL_MAX], row[COL_MAX] );
row0[COL_SUM] += row[COL_SUM];
row0[COL_SUM2] += row[COL_SUM2];
}
for( y = 1; y < vips_image_get_height( stats->out ); y++ ) {
double *row = ARY( stats->out, 0, y );
row[COL_AVG] = row[COL_SUM] / pels;
row[COL_SD] = sqrt( fabs( row[COL_SUM2] -
@ -191,10 +208,10 @@ vips_stats_stop( VipsStatistic *statistic, void *seq )
double *p = ARY( local->out, 0, b + 1 );
double *q = ARY( global->out, 0, b + 1 );
q[COL_MIN] = p[COL_MIN];
q[COL_MAX] = p[COL_MAX];
q[COL_SUM] = p[COL_SUM];
q[COL_SUM2] = p[COL_SUM2];
int i;
for( i = 0; i < COL_LAST; i++ )
q[i] = p[i];
}
global->set = TRUE;
@ -204,8 +221,18 @@ vips_stats_stop( VipsStatistic *statistic, void *seq )
double *p = ARY( local->out, 0, b + 1 );
double *q = ARY( global->out, 0, b + 1 );
q[COL_MIN] = VIPS_MIN( q[COL_MIN], p[COL_MIN] );
q[COL_MAX] = VIPS_MAX( q[COL_MAX], p[COL_MAX] );
if( p[COL_MIN] < q[COL_MIN] ) {
q[COL_MIN] = p[COL_MIN];
q[COL_XMIN] = p[COL_XMIN];
q[COL_YMIN] = p[COL_YMIN];
}
if( p[COL_MAX] > q[COL_MAX] ) {
q[COL_MAX] = p[COL_MAX];
q[COL_XMAX] = p[COL_XMAX];
q[COL_YMAX] = p[COL_YMAX];
}
q[COL_SUM] += p[COL_SUM];
q[COL_SUM2] += p[COL_SUM2];
}
@ -245,29 +272,45 @@ vips_stats_start( VipsStatistic *statistic )
double *q = ARY( local->out, 0, b + 1 ); \
TYPE small, big; \
double sum, sum2; \
int xmin, ymin; \
int xmax, ymax; \
\
if( local->set ) { \
small = q[COL_MIN]; \
big = q[COL_MAX]; \
sum = q[COL_SUM]; \
sum2 = q[COL_SUM2]; \
xmin = q[COL_XMIN]; \
ymin = q[COL_YMIN]; \
xmax = q[COL_XMAX]; \
ymax = q[COL_YMAX]; \
} \
else { \
small = p[0]; \
big = p[0]; \
sum = 0; \
sum2 = 0; \
xmin = x; \
ymin = y; \
xmax = x; \
ymax = y; \
} \
\
for( i = 0; i < n; i++ ) { \
TYPE value = *p; \
\
sum += value;\
sum2 += (double) value * (double) value;\
if( value > big ) \
sum += value; \
sum2 += (double) value * (double) value; \
if( value > big ) { \
big = value; \
else if( value < small ) \
small = value;\
xmax = x + i; \
ymax = y; \
} \
else if( value < small ) { \
small = value; \
xmin = x + i; \
ymin = y; \
} \
\
p += bands; \
} \
@ -276,8 +319,13 @@ vips_stats_start( VipsStatistic *statistic )
q[COL_MAX] = big; \
q[COL_SUM] = sum; \
q[COL_SUM2] = sum2; \
local->set = TRUE; \
q[COL_XMIN] = xmin; \
q[COL_YMIN] = ymin; \
q[COL_XMAX] = xmax; \
q[COL_YMAX] = ymax; \
} \
\
local->set = TRUE; \
}
/* Loop over region, accumulating a sum in *tmp.