hist hacking
This commit is contained in:
parent
81c6456b78
commit
05c5ae9734
@ -4,6 +4,7 @@
|
|||||||
- im_wbuffer2() renamed as vips_discsink(), some cleanups
|
- im_wbuffer2() renamed as vips_discsink(), some cleanups
|
||||||
- im_gammacorrect() can do 16-bit images too
|
- im_gammacorrect() can do 16-bit images too
|
||||||
- im_histplot() could fail for signed int histograms
|
- im_histplot() could fail for signed int histograms
|
||||||
|
- im_fwfft() and im_invfft() could free their output image too early
|
||||||
|
|
||||||
16/1/10 started 7.21.2
|
16/1/10 started 7.21.2
|
||||||
- "invalidate" is careful to keep images alive, so invalidate callbacks can do
|
- "invalidate" is careful to keep images alive, so invalidate callbacks can do
|
||||||
|
3
TODO
3
TODO
@ -2,6 +2,9 @@
|
|||||||
- lots of stupid little files in hist, eg. im_hsp.c ... paste them into larger
|
- lots of stupid little files in hist, eg. im_hsp.c ... paste them into larger
|
||||||
modules
|
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 of decls in hist.h, is it sensible?
|
||||||
|
|
||||||
check the order in freq_flt as well
|
check the order in freq_flt as well
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
* 7/2/10
|
* 7/2/10
|
||||||
* - cleanups
|
* - cleanups
|
||||||
* - gtkdoc
|
* - gtkdoc
|
||||||
|
* 25/3/10
|
||||||
|
* - have a "t" image linked to out to keep the image alive for longer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -573,6 +575,7 @@ im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn )
|
|||||||
{
|
{
|
||||||
IMAGE **bands;
|
IMAGE **bands;
|
||||||
IMAGE **fft;
|
IMAGE **fft;
|
||||||
|
IMAGE *t;
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
if( in->Bands == 1 )
|
if( in->Bands == 1 )
|
||||||
@ -589,7 +592,12 @@ im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn )
|
|||||||
fn( dummy, bands[b], fft[b] ) )
|
fn( dummy, bands[b], fft[b] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( im_gbandjoin( fft, out, in->Bands ) )
|
/* We need a "t" for the combined image that won't get freed too
|
||||||
|
* quickly.
|
||||||
|
*/
|
||||||
|
if( !(t = im_open_local( out, "im__fftproc", "t" )) ||
|
||||||
|
im_gbandjoin( fft, t, in->Bands ) ||
|
||||||
|
im_copy( t, out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
@ -258,7 +258,6 @@ invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
|
|||||||
#endif /*HAVE_FFTW3*/
|
#endif /*HAVE_FFTW3*/
|
||||||
#endif /*HAVE_FFTW*/
|
#endif /*HAVE_FFTW*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* im_invfft:
|
* im_invfft:
|
||||||
* @in: input image
|
* @in: input image
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
* Histogram-equalise @in. Equalise using band @bandno, or if @bandno is -1,
|
* Histogram-equalise @in. Equalise using band @bandno, or if @bandno is -1,
|
||||||
* equalise all bands.
|
* equalise all bands.
|
||||||
*
|
*
|
||||||
* See also: im_histgr(), im_histeq().
|
* See also: im_lhisteq(), im_histgr(), im_histeq().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
|
@ -1,12 +1,4 @@
|
|||||||
/* @(#) Performs local histogram equalisation on an image using a
|
/* local histogram equalisation
|
||||||
* @(#) window of size xw by yw
|
|
||||||
* @(#) Works only on monochrome images
|
|
||||||
* @(#)
|
|
||||||
* @(#) int im_lhisteq(in, out, xwin, ywin)
|
|
||||||
* @(#) IMAGE *in, *out;
|
|
||||||
* @(#) int xwin, ywin;
|
|
||||||
* @(#)
|
|
||||||
* @(#) Returns 0 on sucess and -1 on error
|
|
||||||
*
|
*
|
||||||
* Copyright: 1991, N. Dessipris
|
* Copyright: 1991, N. Dessipris
|
||||||
*
|
*
|
||||||
@ -22,6 +14,9 @@
|
|||||||
* - sets Xoffset/Yoffset
|
* - sets Xoffset/Yoffset
|
||||||
* 23/6/08
|
* 23/6/08
|
||||||
* - check for window too small as well
|
* - check for window too small as well
|
||||||
|
* 25/3/10
|
||||||
|
* - gtkdoc
|
||||||
|
* - small cleanups
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -80,18 +75,12 @@ lhist_gen( REGION *or, void *seq, void *a, void *b )
|
|||||||
{
|
{
|
||||||
REGION *ir = (REGION *) seq;
|
REGION *ir = (REGION *) seq;
|
||||||
LhistInfo *inf = (LhistInfo *) b;
|
LhistInfo *inf = (LhistInfo *) b;
|
||||||
Rect irect;
|
|
||||||
|
|
||||||
Rect *r = &or->valid;
|
Rect *r = &or->valid;
|
||||||
int le = r->left;
|
|
||||||
int to = r->top;
|
|
||||||
int bo = IM_RECT_BOTTOM( r );
|
|
||||||
int ri = IM_RECT_RIGHT( r );
|
|
||||||
|
|
||||||
|
Rect irect;
|
||||||
int x, y, i, j;
|
int x, y, i, j;
|
||||||
int lsk;
|
int lsk;
|
||||||
|
int centre; /* Offset to move to centre of window */
|
||||||
int coff; /* Offset to move to centre of window */
|
|
||||||
|
|
||||||
/* What part of ir do we need?
|
/* What part of ir do we need?
|
||||||
*/
|
*/
|
||||||
@ -99,49 +88,60 @@ lhist_gen( REGION *or, void *seq, void *a, void *b )
|
|||||||
irect.top = or->valid.top;
|
irect.top = or->valid.top;
|
||||||
irect.width = or->valid.width + inf->xwin;
|
irect.width = or->valid.width + inf->xwin;
|
||||||
irect.height = or->valid.height + inf->ywin;
|
irect.height = or->valid.height + inf->ywin;
|
||||||
|
|
||||||
if( im_prepare( ir, &irect ) )
|
if( im_prepare( ir, &irect ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
lsk = IM_REGION_LSKIP( ir );
|
|
||||||
coff = lsk * (inf->ywin / 2) + inf->xwin / 2;
|
|
||||||
|
|
||||||
for( y = to; y < bo; y++ ) {
|
lsk = IM_REGION_LSKIP( ir );
|
||||||
|
centre = lsk * (inf->ywin / 2) + inf->xwin / 2;
|
||||||
|
|
||||||
|
for( y = 0; y < r->height; y++ ) {
|
||||||
/* Get input and output pointers for this line.
|
/* Get input and output pointers for this line.
|
||||||
*/
|
*/
|
||||||
PEL *p = (PEL *) IM_REGION_ADDR( ir, le, y );
|
PEL *p = (PEL *) IM_REGION_ADDR( ir, r->left, r->top + y );
|
||||||
PEL *q = (PEL *) IM_REGION_ADDR( or, le, y );
|
PEL *q = (PEL *) IM_REGION_ADDR( or, r->left, r->top + y );
|
||||||
PEL *p1, *p2;
|
|
||||||
|
PEL *p1;
|
||||||
int hist[256];
|
int hist[256];
|
||||||
|
|
||||||
/* Find histogram for start of this line.
|
/* Find histogram for start of this line.
|
||||||
*/
|
*/
|
||||||
memset( hist, 0, 256 * sizeof( int ) );
|
memset( hist, 0, 256 * sizeof( int ) );
|
||||||
for( p1 = p, j = 0; j < inf->ywin; j++, p1 += lsk )
|
p1 = p;
|
||||||
for( p2 = p1, i = 0; i < inf->xwin; i++, p2++ )
|
for( j = 0; j < inf->ywin; j++ ) {
|
||||||
hist[*p2]++;
|
for( i = 0; i < inf->xwin; i++ )
|
||||||
|
hist[p1[i]] += 1;
|
||||||
|
|
||||||
|
p1 += lsk;
|
||||||
|
}
|
||||||
|
|
||||||
/* Loop for output pels.
|
/* Loop for output pels.
|
||||||
*/
|
*/
|
||||||
for( x = le; x < ri; x++, p++ ) {
|
for( x = 0; x < r->width; x++ ) {
|
||||||
/* Sum histogram up to current pel.
|
/* Sum histogram up to current pel.
|
||||||
*/
|
*/
|
||||||
int target = p[coff];
|
int target = p[centre];
|
||||||
int sum = 0;
|
int sum;
|
||||||
|
|
||||||
for( sum = 0, i = 0; i < target; i++ )
|
sum = 0;
|
||||||
|
for( i = 0; i < target; i++ )
|
||||||
sum += hist[i];
|
sum += hist[i];
|
||||||
|
|
||||||
/* Transform.
|
/* Transform.
|
||||||
*/
|
*/
|
||||||
*q++ = sum * 256 / inf->npels;
|
q[x] = sum * 256 / inf->npels;
|
||||||
|
|
||||||
/* Adapt histogram - remove the pels from the left hand
|
/* Adapt histogram - remove the pels from the left hand
|
||||||
* column, add in pels for a new right-hand column.
|
* column, add in pels for a new right-hand column.
|
||||||
*/
|
*/
|
||||||
for( p1 = p, j = 0; j < inf->ywin; j++, p1 += lsk ) {
|
p1 = p;
|
||||||
hist[p1[0]]--;
|
for( j = 0; j < inf->ywin; j++ ) {
|
||||||
hist[p1[inf->xwin]]++;
|
hist[p1[0]] -= 1;
|
||||||
|
hist[p1[inf->xwin]] += 1;
|
||||||
|
|
||||||
|
p1 += lsk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,22 +153,22 @@ im_lhisteq_raw( IMAGE *in, IMAGE *out, int xwin, int ywin )
|
|||||||
{
|
{
|
||||||
LhistInfo *inf;
|
LhistInfo *inf;
|
||||||
|
|
||||||
if( im_piocheck( in, out ) )
|
if( im_check_mono( "im_lhisteq", in ) ||
|
||||||
|
im_check_uncoded( "im_lhisteq", in ) ||
|
||||||
|
im_check_format( "im_lhisteq", in, IM_BANDFMT_UCHAR ) ||
|
||||||
|
im_piocheck( in, out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( in->BandFmt != IM_BANDFMT_UCHAR ||
|
if( xwin > in->Xsize ||
|
||||||
in->Bands != 1 || in->Coding != IM_CODING_NONE ) {
|
ywin > in->Ysize ) {
|
||||||
im_error( "im_lhisteq",
|
|
||||||
"%s", _( "one band uchar uncoded only" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
if( xwin > in->Xsize || ywin > in->Ysize ) {
|
|
||||||
im_error( "im_lhisteq", "%s", _( "window too large" ) );
|
im_error( "im_lhisteq", "%s", _( "window too large" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
if( xwin <= 0 || ywin <= 0 ) {
|
if( xwin <= 0 ||
|
||||||
|
ywin <= 0 ) {
|
||||||
im_error( "im_lhisteq", "%s", _( "window too small" ) );
|
im_error( "im_lhisteq", "%s", _( "window too small" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( im_cp_desc( out, in ) )
|
if( im_cp_desc( out, in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
out->Xsize -= xwin - 1;
|
out->Xsize -= xwin - 1;
|
||||||
@ -188,8 +188,6 @@ im_lhisteq_raw( IMAGE *in, IMAGE *out, int xwin, int ywin )
|
|||||||
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
|
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Write the hist.
|
|
||||||
*/
|
|
||||||
if( im_generate( out,
|
if( im_generate( out,
|
||||||
im_start_one, lhist_gen, im_stop_one, in, inf ) )
|
im_start_one, lhist_gen, im_stop_one, in, inf ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -200,14 +198,30 @@ im_lhisteq_raw( IMAGE *in, IMAGE *out, int xwin, int ywin )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The above, with a border to make out the same size as in.
|
/**
|
||||||
|
* im_lhisteq:
|
||||||
|
* @in: input image
|
||||||
|
* @out: output image
|
||||||
|
* @xwin: width of region
|
||||||
|
* @hwin: height of region
|
||||||
|
*
|
||||||
|
* Performs local histogram equalisation on @in using a
|
||||||
|
* window of size @xwin by @ywin centered on the input pixel. Works only on
|
||||||
|
* monochrome images.
|
||||||
|
*
|
||||||
|
* The output image is the same size as the input image. The edge pixels are
|
||||||
|
* created by copy edge pixels of the input image outwards.
|
||||||
|
*
|
||||||
|
* See also: im_heq().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
im_lhisteq( IMAGE *in, IMAGE *out, int xwin, int ywin )
|
im_lhisteq( IMAGE *in, IMAGE *out, int xwin, int ywin )
|
||||||
{
|
{
|
||||||
IMAGE *t1 = im_open_local( out, "im_lhisteq:1", "p" );
|
IMAGE *t1;
|
||||||
|
|
||||||
if( !t1 ||
|
if( !(t1 = im_open_local( out, "im_lhisteq:1", "p" )) ||
|
||||||
im_embed( in, t1, 1,
|
im_embed( in, t1, 1,
|
||||||
xwin / 2, ywin / 2,
|
xwin / 2, ywin / 2,
|
||||||
in->Xsize + xwin - 1, in->Ysize + ywin - 1 ) ||
|
in->Xsize + xwin - 1, in->Ysize + ywin - 1 ) ||
|
||||||
|
@ -1,28 +1,4 @@
|
|||||||
/* @(#) Map an image through another image, acting as a LUT (Look Up Table).
|
/* map though a LUT
|
||||||
* @(#) 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.
|
|
||||||
* @(#)
|
|
||||||
* @(#) If the input is IM_BANDFMT_UCHAR, then the LUT must have 256 elements,
|
|
||||||
* @(#) in other words, lut->Xsize * lut->Ysize == 256.
|
|
||||||
* @(#)
|
|
||||||
* @(#) If the input is IM_BANDFMT_USHORT or IM_BANDFMT_UINT, then the lut
|
|
||||||
* @(#) may have any number of elements, and input pels whose value is
|
|
||||||
* @(#) greater than lut->Xsize * lut->Ysize are mapped with the last LUT
|
|
||||||
* @(#) element.
|
|
||||||
* @(#)
|
|
||||||
* @(#) If LUT has one band, then all bands of input pass through it. If LUT
|
|
||||||
* @(#) has same number of bands as input, then each band is LUTed
|
|
||||||
* @(#) separately. If input has one band, then LUT may have many bands and
|
|
||||||
* @(#) the output will have the same number of bands as the LUT.
|
|
||||||
* @(#)
|
|
||||||
* @(#) int
|
|
||||||
* @(#) im_maplut( in, out, lut )
|
|
||||||
* @(#) IMAGE *in, *out, *lut;
|
|
||||||
* @(#)
|
|
||||||
* @(#) Returns 0 on success and -1 on error
|
|
||||||
* @(#)
|
|
||||||
*
|
*
|
||||||
* Modified:
|
* Modified:
|
||||||
* 18/6/93 JC
|
* 18/6/93 JC
|
||||||
@ -50,6 +26,9 @@
|
|||||||
* years :-)
|
* years :-)
|
||||||
* 7/11/07
|
* 7/11/07
|
||||||
* - new eval start/end system
|
* - new eval start/end system
|
||||||
|
* 25/3/10
|
||||||
|
* - gtkdoc
|
||||||
|
* - small cleanups
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -130,11 +109,11 @@ lut_end( LutInfo *st )
|
|||||||
static LutInfo *
|
static LutInfo *
|
||||||
build_luts( IMAGE *out, IMAGE *lut )
|
build_luts( IMAGE *out, IMAGE *lut )
|
||||||
{
|
{
|
||||||
LutInfo *st = IM_NEW( out, LutInfo );
|
LutInfo *st;
|
||||||
int i, x;
|
int i, x;
|
||||||
PEL *q;
|
PEL *q;
|
||||||
|
|
||||||
if( !st )
|
if( !(st = IM_NEW( out, LutInfo )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
|
||||||
/* Make luts. We unpack the LUT image into a C 2D array to speed
|
/* Make luts. We unpack the LUT image into a C 2D array to speed
|
||||||
@ -244,15 +223,15 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
for( y = to; y < bo; y++ ) { \
|
for( y = to; y < bo; y++ ) { \
|
||||||
for( z = 0; z < b; z++ ) { \
|
for( z = 0; z < b; z++ ) { \
|
||||||
PEL *p = (PEL *) IM_REGION_ADDR( ir, le, y ) + z; \
|
PEL *p = (PEL *) IM_REGION_ADDR( ir, le, y ) + z; \
|
||||||
OUT *q = (OUT *) IM_REGION_ADDR( or, le, y ) + z*2; \
|
OUT *q = (OUT *) IM_REGION_ADDR( or, le, y ) + z * 2; \
|
||||||
OUT *tlut = (OUT *) st->table[z]; \
|
OUT *tlut = (OUT *) st->table[z]; \
|
||||||
\
|
\
|
||||||
for( x = 0; x < ne; x += b ) { \
|
for( x = 0; x < ne; x += b ) { \
|
||||||
int n = p[x]*2; \
|
int n = p[x] * 2; \
|
||||||
\
|
\
|
||||||
q[0] = tlut[n]; \
|
q[0] = tlut[n]; \
|
||||||
q[1] = tlut[n + 1]; \
|
q[1] = tlut[n + 1]; \
|
||||||
q += b*2; \
|
q += b * 2; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -287,7 +266,7 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
for( y = to; y < bo; y++ ) { \
|
for( y = to; y < bo; y++ ) { \
|
||||||
for( z = 0; z < b; z++ ) { \
|
for( z = 0; z < b; z++ ) { \
|
||||||
IN *p = (IN *) IM_REGION_ADDR( ir, le, y ) + z; \
|
IN *p = (IN *) IM_REGION_ADDR( ir, le, y ) + z; \
|
||||||
OUT *q = (OUT *) IM_REGION_ADDR( or, le, y ) + z*2; \
|
OUT *q = (OUT *) IM_REGION_ADDR( or, le, y ) + z * 2; \
|
||||||
OUT *tlut = (OUT *) st->table[z]; \
|
OUT *tlut = (OUT *) st->table[z]; \
|
||||||
\
|
\
|
||||||
for( x = 0; x < ne; x += b ) { \
|
for( x = 0; x < ne; x += b ) { \
|
||||||
@ -298,10 +277,10 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
seq->overflow++; \
|
seq->overflow++; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
q[0] = tlut[ index*2 ]; \
|
q[0] = tlut[index * 2]; \
|
||||||
q[1] = tlut[ index*2+1 ]; \
|
q[1] = tlut[index * 2 + 1]; \
|
||||||
\
|
\
|
||||||
q += b*2; \
|
q += b * 2; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -378,8 +357,8 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
seq->overflow++; \
|
seq->overflow++; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
q[0] = tlut[index*2]; \
|
q[0] = tlut[index * 2]; \
|
||||||
q[1] = tlut[index*2 + 1]; \
|
q[1] = tlut[index * 2 + 1]; \
|
||||||
q += 2; \
|
q += 2; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -465,8 +444,8 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
for( z = 0; z < st->nb; z++ ) { \
|
for( z = 0; z < st->nb; z++ ) { \
|
||||||
q[0] = tlut[z][n*2]; \
|
q[0] = tlut[z][n * 2]; \
|
||||||
q[1] = tlut[z][n*2 + 1]; \
|
q[1] = tlut[z][n * 2 + 1]; \
|
||||||
q += 2; \
|
q += 2; \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
@ -481,8 +460,7 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
case IM_BANDFMT_USHORT: GEN( unsigned short, OUT ); break; \
|
case IM_BANDFMT_USHORT: GEN( unsigned short, OUT ); break; \
|
||||||
case IM_BANDFMT_UINT: GEN( unsigned int, OUT ); break; \
|
case IM_BANDFMT_UINT: GEN( unsigned int, OUT ); break; \
|
||||||
default: \
|
default: \
|
||||||
im_error( "im_maplut", "%s", _( "bad input file" ) ); \
|
g_assert( 0 ); \
|
||||||
return( -1 ); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Switch for LUT types. One function for non-complex images, a
|
/* Switch for LUT types. One function for non-complex images, a
|
||||||
@ -512,8 +490,7 @@ maplut_start( IMAGE *out, void *a, void *b )
|
|||||||
case IM_BANDFMT_DPCOMPLEX: inner_switch( UCHAR_FC, GEN_FC, \
|
case IM_BANDFMT_DPCOMPLEX: inner_switch( UCHAR_FC, GEN_FC, \
|
||||||
double ); break; \
|
double ); break; \
|
||||||
default: \
|
default: \
|
||||||
im_error( "im_maplut", "%s", _( "bad lut file" ) ); \
|
g_assert( 0 ); \
|
||||||
return( -1 ); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do a map.
|
/* Do a map.
|
||||||
@ -529,8 +506,8 @@ maplut_gen( REGION *or, void *vseq, void *a, void *b )
|
|||||||
int le = r->left;
|
int le = r->left;
|
||||||
int to = r->top;
|
int to = r->top;
|
||||||
int bo = IM_RECT_BOTTOM(r);
|
int bo = IM_RECT_BOTTOM(r);
|
||||||
int np = r->width; /* Pels across region */
|
int np = r->width; /* Pels across region */
|
||||||
int ne = IM_REGION_N_ELEMENTS( or ); /* Number of elements */
|
int ne = IM_REGION_N_ELEMENTS( or ); /* Number of elements */
|
||||||
int x, y, z, i;
|
int x, y, z, i;
|
||||||
|
|
||||||
/* Get input ready.
|
/* Get input ready.
|
||||||
@ -557,51 +534,49 @@ maplut_gen( REGION *or, void *vseq, void *a, void *b )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* im_maplut:
|
||||||
|
* @in: input image
|
||||||
|
* @out: output image
|
||||||
|
* @lut: look-up table
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* by copying the last element. Overflows are reported at the end of
|
||||||
|
* computation.
|
||||||
|
* If @lut is too large, extra values are ignored.
|
||||||
|
*
|
||||||
|
* If @lut has one band, then all bands of @in pass through it. If @lut
|
||||||
|
* has same number of bands as @in, then each band is mapped
|
||||||
|
* separately. If @in has one band, then @lut may have many bands and
|
||||||
|
* the output will have the same number of bands as @lut.
|
||||||
|
*
|
||||||
|
* See also: im_histgr(), im_identity().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
|
im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
|
||||||
{
|
{
|
||||||
LutInfo *st;
|
LutInfo *st;
|
||||||
|
|
||||||
/* Check lut.
|
|
||||||
*/
|
|
||||||
if( lut->Coding != IM_CODING_NONE ) {
|
|
||||||
im_error( "im_maplut", "%s", _( "lut is not uncoded" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
if( lut->Xsize * lut->Ysize > 100000 ) {
|
|
||||||
im_error( "im_maplut", "%s", _( "lut seems very large!" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check input output. Old-style IO from lut, for simplicity.
|
/* Check input output. Old-style IO from lut, for simplicity.
|
||||||
*/
|
*/
|
||||||
if( im_piocheck( in, out ) || im_incheck( lut ) )
|
if( im_check_hist( "im_maplut", 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 );
|
return( -1 );
|
||||||
|
|
||||||
/* Check args.
|
|
||||||
*/
|
|
||||||
if( in->Coding != IM_CODING_NONE ) {
|
|
||||||
im_error( "im_maplut", "%s", _( "input is not uncoded" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
if( !vips_bandfmt_isuint( in->BandFmt ) ) {
|
|
||||||
im_error( "im_maplut", "%s",
|
|
||||||
_( "input is not some unsigned integer type" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
if( in->Bands != 1 && lut->Bands != 1 && lut->Bands != in->Bands ) {
|
|
||||||
im_error( "im_maplut", "%s", _( "lut should have 1 band, "
|
|
||||||
"or same number of bands as input, "
|
|
||||||
"or any number of bands if input has 1 band" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
if( in->BandFmt == IM_BANDFMT_UCHAR &&
|
|
||||||
lut->Xsize * lut->Ysize != 256 ) {
|
|
||||||
im_error( "im_maplut", "%s", _( "input is uchar and lut "
|
|
||||||
"does not have 256 elements" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare the output header.
|
/* Prepare the output header.
|
||||||
*/
|
*/
|
||||||
if( im_cp_descv( out, in, lut, NULL ) )
|
if( im_cp_descv( out, in, lut, NULL ) )
|
||||||
|
@ -1,19 +1,4 @@
|
|||||||
/* @(#) Function which returns an int. This integer is the threshold
|
/* find percent of pixels
|
||||||
* @(#) above which there are percent values of the input images
|
|
||||||
* @(#) If for instance precent=.1, the number of pels of the input image
|
|
||||||
* @(#) with values greater than the returned int will correspond to
|
|
||||||
* @(#) 10% of all pels of the image.
|
|
||||||
* @(#) One band IM_BANDFMT_UCHAR images only.
|
|
||||||
* @(#)
|
|
||||||
* @(#) Function im_mpercent() assumes that input
|
|
||||||
* @(#) is either memory mapped or in a buffer.
|
|
||||||
* @(#)
|
|
||||||
* @(#) int im_percent(in, percent)
|
|
||||||
* @(#) IMAGE *in;
|
|
||||||
* @(#) double percent;
|
|
||||||
* @(#)
|
|
||||||
* @(#) Returns 0 on success and -1 on error
|
|
||||||
*
|
|
||||||
* Copyright: 1990, N. Dessipris
|
* Copyright: 1990, N. Dessipris
|
||||||
*
|
*
|
||||||
* Author: N. Dessipris
|
* Author: N. Dessipris
|
||||||
@ -24,6 +9,8 @@
|
|||||||
* - ANSIfied a little
|
* - ANSIfied a little
|
||||||
* 19/1/07
|
* 19/1/07
|
||||||
* - redone with the vips hist operators
|
* - redone with the vips hist operators
|
||||||
|
* 25/3/10
|
||||||
|
* - gtkdoc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,8 +53,23 @@
|
|||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#endif /*WITH_DMALLOC*/
|
#endif /*WITH_DMALLOC*/
|
||||||
|
|
||||||
/* What threshold will select a specified percentage of the pixels in the
|
/**
|
||||||
* image.
|
* im_mpercent:
|
||||||
|
* @in: input image
|
||||||
|
* @percent: threshold percentage
|
||||||
|
* @out: output threshold value
|
||||||
|
*
|
||||||
|
* im_mpercent() returns (through the @out parameter) the threshold above
|
||||||
|
* which there are @percent values of @in. If for example percent=.1, the
|
||||||
|
* number of pels of the input image with values greater than the returned
|
||||||
|
* int will correspond to 10% of all pels of the image.
|
||||||
|
*
|
||||||
|
* The function works for uchar and ushort images only. It can be used
|
||||||
|
* to threshold the scaled result of a filtering operation.
|
||||||
|
*
|
||||||
|
* See also: im_histgr(), im_profile().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
im_mpercent( IMAGE *in, double percent, int *out )
|
im_mpercent( IMAGE *in, double percent, int *out )
|
||||||
|
Loading…
Reference in New Issue
Block a user