hist hacking

This commit is contained in:
John Cupitt 2010-03-26 17:32:29 +00:00
parent f0f75b4093
commit d19a117861
6 changed files with 112 additions and 40 deletions

View File

@ -6,6 +6,8 @@
- im_histplot() could fail for signed int histograms
- im_fwfft() and im_invfft() could free their output image too early
- added im_local_imask(), im_local_dmask()
- added im_mpercent_hist()
- im_maplut() casts the index image to one of the uint types
16/1/10 started 7.21.2
- "invalidate" is careful to keep images alive, so invalidate callbacks can do

19
TODO
View File

@ -1,4 +1,9 @@
- expose more of the tone funcs in nip2
- quite a few hist operations have no GUI ... lhisteq, for example? or
histspec?
- conv with scale == 0 gives /0 error
- added im_local_imask(), im_local_dmask(), needs docs?
@ -7,22 +12,20 @@
is local_imask() in the best place? shouldn't it be in mask.h?
- im_tone_analyse() needs docs and testing
also im_tone_map()
- im_rotate_imask90 only works for square, odd-sized massks, argh
- im_rotate_imask90 only works for square, odd-sized masks, argh
- lots of stupid little files in hist, eg. im_hsp.c ... paste them into larger
modules
- quite a few hist operations have no GUI ... lhisteq, for example? or
histspec?
- check the order of decls in hist.h, is it sensible?
check the order in freq_flt as well
- im_render() should be renamed as vips_sink_screen()? also vips_sink_disc()
instead of vips_discsink()?

View File

@ -534,6 +534,19 @@ maplut_gen( REGION *or, void *vseq, void *a, void *b )
return( 0 );
}
/* Save a bit of typing.
*/
#define UC IM_BANDFMT_UCHAR
#define US IM_BANDFMT_USHORT
#define UI IM_BANDFMT_UINT
/* Type mapping: go to uchar or ushort.
*/
static int bandfmt_maplut[10] = {
/* UC C US S UI I F X D DX */
UC, UC, US, US, UI, UI, UI, UI, UI, UI
};
/**
* im_maplut:
* @in: input image
@ -543,8 +556,8 @@ maplut_gen( REGION *or, void *vseq, void *a, void *b )
* Map an image through another image acting as a LUT (Look Up Table).
* The lut may have any type, and the output image will be that type.
*
* The input image must be an unsigned integer types, that is, it must
* be one of IM_BANDFMT_UCHAR, IM_BANDFMT_USHORT or IM_BANDFMT_UINT.
* The input image will be cast to one of the unsigned integer types, that is,
* IM_BANDFMT_UCHAR, IM_BANDFMT_USHORT or IM_BANDFMT_UINT.
*
* If @lut is too small for the input type (for example, if @in is
* IM_BANDFMT_UCHAR but @lut only has 100 elements), the lut is padded out
@ -564,6 +577,7 @@ maplut_gen( REGION *or, void *vseq, void *a, void *b )
int
im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
{
IMAGE *t;
LutInfo *st;
/* Check input output. Old-style IO from lut, for simplicity.
@ -572,14 +586,19 @@ im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
im_check_uncoded( "im_maplut", lut ) ||
im_check_uncoded( "im_maplut", in ) ||
im_check_bands_1orn( "im_maplut", in, lut ) ||
im_check_uint( "im_maplut", in ) ||
im_piocheck( in, out ) ||
im_incheck( lut ) )
return( -1 );
/* Cast in to u8/u16.
*/
if( !(t = im_open_local( out, "im_maplut", "p" )) ||
im_clip2fmt( in, t, bandfmt_maplut[in->BandFmt] ) )
return( -1 );
/* Prepare the output header.
*/
if( im_cp_descv( out, in, lut, NULL ) )
if( im_cp_descv( out, t, lut, NULL ) )
return( -1 );
/* Force output to be the same type as lut.
@ -599,12 +618,12 @@ im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
/* Set demand hints.
*/
if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
if( im_demand_hint( out, IM_THINSTRIP, t, NULL ) )
return( -1 );
/* Process!
*/
if( im_generate( out, maplut_start, maplut_gen, maplut_stop, in, st ) )
if( im_generate( out, maplut_start, maplut_gen, maplut_stop, t, st ) )
return( -1 );
return( 0 );

View File

@ -53,6 +53,53 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/**
* im_mpercent_hist:
* @hist: input histogram image
* @percent: threshold percentage
* @out: output threshold value
*
* Just like im_mpercent(), except it works on an image histogram. Handy if
* you want to run im_mpercent() several times without having to recompute the
* histogram each time.
*
* See also: im_mpercent().
*
* Returns: 0 on success, -1 on error
*/
int
im_mpercent_hist( IMAGE *hist, double percent, int *out )
{
IMAGE *base;
IMAGE *t[6];
double pos;
if( im_check_hist( "im_mpercent", hist ) )
return( -1 );
if( !(base = im_open( "im_mpercent", "p" )) )
return( -1 );
if( im_open_local_array( base, t, 6, "im_mpercent", "p" ) ) {
im_close( base );
return( -1 );
}
if( im_histcum( hist, t[1] ) ||
im_histnorm( t[1], t[2] ) ||
im_lessconst( t[2], t[3], percent * t[2]->Xsize ) ||
im_fliphor( t[3], t[4] ) ||
im_profile( t[4], t[5], 1 ) ||
im_avg( t[5], &pos ) ) {
im_close( base );
return( -1 );
}
im_close( base );
*out = pos;
return( 0 );
}
/**
* im_mpercent:
* @in: input image
@ -73,31 +120,17 @@
*/
int
im_mpercent( IMAGE *in, double percent, int *out )
{
IMAGE *base;
IMAGE *t[6];
double pos;
{
IMAGE *t;
if( !(base = im_open( "im_mpercent1", "p" )) )
if( !(t = im_open( "im_mpercent1", "p" )) )
return( -1 );
if( im_open_local_array( base, t, 6, "im_mpercent", "p" ) ) {
im_close( base );
if( im_histgr( in, t, -1 ) ||
im_mpercent_hist( t, percent, out ) ) {
im_close( t );
return( -1 );
}
if( im_histgr( in, t[0], -1 ) ||
im_histcum( t[0], t[1] ) ||
im_histnorm( t[1], t[2] ) ||
im_lessconst( t[2], t[3], percent * t[2]->Xsize ) ||
im_fliphor( t[3], t[4] ) ||
im_profile( t[4], t[5], 1 ) ||
im_avg( t[5], &pos ) ) {
im_close( base );
return( -1 );
}
im_close( base );
*out = pos;
im_close( t );
return( 0 );
}

View File

@ -427,9 +427,23 @@ im_tone_map( IMAGE *in, IMAGE *out, IMAGE *lut )
return( im_copy( t[4], out ) );
}
/* Find histogram of in, and use that to set Lb, Lw levels.
* @(#) im_tone_analyse: find the histogram of a LabS or LabQ image and use
* @(#) that to set the Ln and Lw parameters of im_tone_build()
/**
* im_tone_analyse:
* in: input image
* out: output image
* Ps: shadow point (eg. 0.2)
* Pm: mid-tone point (eg. 0.5)
* Ph: highlight point (eg. 0.8)
* S: shadow adjustment (+/- 30)
* M: mid-tone adjustment (+/- 30)
* H: highlight adjustment (+/- 30)
*
* As im_tone_build(), but analyse the histogram of @in and use it to
* pick the 0.1% and 99.9% points for @Lb and @Lw.
*
* See also: im_tone_build().
*
* Returns: 0 on success, -1 on error
*/
int
im_tone_analyse(
@ -466,8 +480,8 @@ im_tone_analyse(
im_histgr( t[2], t[3], -1 ) )
return( -1 );
if( im_mpercent( t[3], 0.1 / 100.0, &low ) ||
im_mpercent( t[3], 99.9 / 100.0, &high ) )
if( im_mpercent_hist( t[3], 0.1 / 100.0, &high ) ||
im_mpercent_hist( t[3], 99.9 / 100.0, &low ) )
return( -1 );
Lb = 100 * low / 32768;

View File

@ -70,6 +70,7 @@ int im_ismonotonic( IMAGE *lut, int *out );
int im_tone_map( IMAGE *in, IMAGE *out, IMAGE *lut );
int im_project( IMAGE *in, IMAGE *hout, IMAGE *vout );
int im_mpercent( IMAGE *in, double percent, int *out );
int im_mpercent_hist( IMAGE *hist, double percent, int *out );
#ifdef __cplusplus
}