add combine mode to find_indexed

This commit is contained in:
John Cupitt 2017-11-03 16:36:09 +00:00
parent 487c112807
commit 4ea743f5e6
2 changed files with 49 additions and 8 deletions

View File

@ -34,6 +34,7 @@
- fix build with gcc 7 - fix build with gcc 7
- add vips_fill_nearest() ... fill pixels with nearest colour - add vips_fill_nearest() ... fill pixels with nearest colour
- add VIPS_COMBINE_MIN, a new combining mode for vips_compass() - add VIPS_COMBINE_MIN, a new combining mode for vips_compass()
- vips_hist_find_indexed() now has a @combine parameter
29/8/17 started 8.5.9 29/8/17 started 8.5.9
- make --fail stop jpeg read on any libjpeg warning, thanks @mceachen - make --fail stop jpeg read on any libjpeg warning, thanks @mceachen

View File

@ -6,6 +6,8 @@
* - gtkdoc * - gtkdoc
* 17/8/13 * 17/8/13
* - redo as a class * - redo as a class
* 2/11/17
* - add @combine ... pick a bin combine mode
*/ */
/* /*
@ -79,6 +81,10 @@ typedef struct _VipsHistFindIndexed {
*/ */
VipsImage *out; VipsImage *out;
/* Combine bins with this.
*/
VipsCombine combine;
} VipsHistFindIndexed; } VipsHistFindIndexed;
typedef VipsStatisticClass VipsHistFindIndexedClass; typedef VipsStatisticClass VipsHistFindIndexedClass;
@ -196,6 +202,27 @@ vips_hist_find_indexed_start( VipsStatistic *statistic )
return( (void *) histogram_new( indexed ) ); return( (void *) histogram_new( indexed ) );
} }
/* Combine B with A according to mode.
*/
#define COMBINE( MODE, A, B ) G_STMT_START { \
switch( MODE ) { \
case VIPS_COMBINE_MAX: \
(A) = VIPS_MAX( A, B ); \
break; \
\
case VIPS_COMBINE_SUM: \
(A) += (B); \
break; \
\
case VIPS_COMBINE_MIN: \
(A) = VIPS_MIN( A, B ); \
break; \
\
default: \
g_assert_not_reached(); \
} \
} G_STMT_END
/* Join a sub-hist onto the main hist. /* Join a sub-hist onto the main hist.
*/ */
static int static int
@ -211,10 +238,8 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq )
/* Add on sub-data. /* Add on sub-data.
*/ */
hist->mx = VIPS_MAX( hist->mx, sub_hist->mx ); hist->mx = VIPS_MAX( hist->mx, sub_hist->mx );
for( i = 0; i < bands * hist->size; i++ ) { for( i = 0; i < bands * hist->size; i++ )
hist->bins[i] += sub_hist->bins[i]; COMBINE( indexed->combine, hist->bins[i], sub_hist->bins[i] );
sub_hist->bins[i] = 0;
}
VIPS_UNREF( sub_hist->reg ); VIPS_UNREF( sub_hist->reg );
@ -231,7 +256,7 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq )
double *bin = hist->bins + i[x] * bands; \ double *bin = hist->bins + i[x] * bands; \
\ \
for( z = 0; z < bands; z++ ) \ for( z = 0; z < bands; z++ ) \
bin[z] += tv[z]; \ COMBINE( indexed->combine, bin[z], tv[z] ); \
\ \
tv += bands; \ tv += bands; \
} \ } \
@ -288,7 +313,7 @@ vips_hist_find_indexed_uchar_scan( VipsHistFindIndexed *indexed,
mx = ix; \ mx = ix; \
\ \
for( z = 0; z < bands; z++ ) \ for( z = 0; z < bands; z++ ) \
bin[z] += tv[z]; \ COMBINE( indexed->combine, bin[z], tv[z] ); \
\ \
tv += bands; \ tv += bands; \
} \ } \
@ -393,11 +418,19 @@ vips_hist_find_indexed_class_init( VipsHistFindIndexedClass *class )
VIPS_ARGUMENT_REQUIRED_OUTPUT, VIPS_ARGUMENT_REQUIRED_OUTPUT,
G_STRUCT_OFFSET( VipsHistFindIndexed, out ) ); G_STRUCT_OFFSET( VipsHistFindIndexed, out ) );
VIPS_ARG_ENUM( class, "combine", 104,
_( "Combine" ),
_( "Combine bins like this" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsHistFindIndexed, combine ),
VIPS_TYPE_COMBINE, VIPS_COMBINE_SUM );
} }
static void static void
vips_hist_find_indexed_init( VipsHistFindIndexed *hist_find ) vips_hist_find_indexed_init( VipsHistFindIndexed *indexed )
{ {
indexed->combine = VIPS_COMBINE_SUM;
} }
/** /**
@ -407,13 +440,20 @@ vips_hist_find_indexed_init( VipsHistFindIndexed *hist_find )
* @out: (out): output image * @out: (out): output image
* @...: %NULL-terminated list of optional named arguments * @...: %NULL-terminated list of optional named arguments
* *
* Optional arguments:
*
* * @combine: #VipsCombine, combine bins like this
*
* Make a histogram of @in, but use image @index to pick the bins. In other * Make a histogram of @in, but use image @index to pick the bins. In other
* words, element zero in @out contains the sum of all the pixels in @in * words, element zero in @out contains the combination of all the pixels in @in
* whose corresponding pixel in @index is zero. * whose corresponding pixel in @index is zero.
* *
* @index must have just one band and be u8 or u16. @in must be * @index must have just one band and be u8 or u16. @in must be
* non-complex. @out always has the same size and format as @in. * non-complex. @out always has the same size and format as @in.
* *
* Normally, bins are summed, but you can use @combine to set other combine
* modes.
*
* This operation is useful in conjunction with vips_labelregions(). You can * This operation is useful in conjunction with vips_labelregions(). You can
* use it to find the centre of gravity of blobs in an image, for example. * use it to find the centre of gravity of blobs in an image, for example.
* *