convolution docs

This commit is contained in:
John Cupitt 2010-02-03 16:24:05 +00:00
parent 97cc8327ca
commit 2932f383bc
16 changed files with 525 additions and 327 deletions

View File

@ -37,11 +37,11 @@
<xi:include href="xml/relational.xml"/>
<xi:include href="xml/colour.xml"/>
<xi:include href="xml/conversion.xml"/>
<xi:include href="xml/convolution.xml"/>
</chapter>
<chapter>
<title>VIPS operation API by section (no gtkdoc comments yet)</title>
<xi:include href="xml/convolution.xml"/>
<xi:include href="xml/format.xml"/>
<xi:include href="xml/morphology.xml"/>
<xi:include href="xml/resample.xml"/>

View File

@ -105,7 +105,7 @@ gnoise_gen( REGION *or, void *seq, void *a, void *b )
/**
* im_gaussnoise:
* @out: output #IMAGE
* @out: output image
* @x: output width
* @y: output height
* @mean: average value in output
@ -115,7 +115,7 @@ gnoise_gen( REGION *or, void *seq, void *a, void *b )
* distribution. The noise distribution is created by averaging 12 random
* numbers with the appropriate weights.
*
* See also: im_make_xy(), im_text(), im_black().
* See also: im_addgnoise(), im_make_xy(), im_text(), im_black().
*
* Returns: 0 on success, -1 on error
*/

View File

@ -113,6 +113,15 @@ system_image( IMAGE *im,
*
* In all cases, @log must be freed with im_free().
*
* For example, this call will run the ImageMagick convert program on an
* image, using JPEG files to pass images into and out of the convert command.
*
* |[
* im_system_image( in, out,
* "%s.jpg", "%s.jpg", "convert %s -swirl 45 %s",
* &log )
* ]|
*
* See also: im_system().
*
* Returns: an image on success, NULL on error

View File

@ -1,15 +1,4 @@
/* @(#) Add gaussian noise with mean 0 and variance sigma to image
* @(#) The noise is generated by averaging 12 random numbers
* @(#) page 78 PIETGEN 1989 n = 12
* @(#) Input image is any, output is float
* @(#) If running on SYSTEM V CONSTANT should be replaced by 2**15 - 1
* @(#) Usage
* @(#)
* @(#) int im_addgnoise(imin, imout, sigma)
* @(#) IMAGE *imin, *imout;
* @(#) double sigma;
* @(#) Returns 0 on success and -1 on error
* @(#)
/* im_addgnoise
*
* Copyright 1990, N. Dessipris.
*
@ -26,6 +15,9 @@
* 2008-01-28 tcv:
* - now works (was broken)
* - no limit on bands
* 4/2/10
* - no need to bandup here now, im_add() does that
* - gtkdoc
*/
/*
@ -66,25 +58,29 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/**
* im_addgnoise:
* @in: input image
* @out: output image
* @sigma: standard deviation of noise
*
* Add gaussian noise with mean 0 and variance sigma to @in.
* The noise is generated by averaging 12 random numbers,
* see page 78, PIETGEN, 1989.
*
* See also: im_gaussnoise().
*
* Returns: 0 on success, -1 on error
*/
int
im_addgnoise( IMAGE *in, IMAGE *out, double sigma ){
#define FUNCTION_NAME "im_addgnoise"
im_addgnoise( IMAGE *in, IMAGE *out, double sigma )
{
IMAGE *t;
if( im_piocheck( in, out ))
return -1;
{
int i;
IMAGE **temps= IM_ARRAY( out, in-> Bands, IMAGE* );
IMAGE *joined_temps= im_open_local( out, FUNCTION_NAME ": joined_temps", "p" );
if( !(t = im_open_local( out, "im_addgnoise", "p" )) ||
im_gaussnoise( t, in->Xsize, in->Ysize, 0, sigma ) ||
im_add( in, t, out ) )
return( -1 );
if( ! temps || ! joined_temps || im_open_local_array( out, temps, in-> Bands, FUNCTION_NAME ": temps", "p" ))
return -1;
for( i= 0; i < in-> Bands; ++i )
if( im_gaussnoise( temps[i], in-> Xsize, in-> Ysize, 0.0, sigma ))
return -1;
return im_gbandjoin( temps, joined_temps, in-> Bands ) || im_add( in, joined_temps, out );
}
#undef FUNCTION_NAME
return( 0 );
}

View File

@ -1,28 +1,12 @@
/* @(#) im_complass: Optimised convolution for line detection
* @(#) Uses the entered mask and 7 rotated versions of it (each by 45 degrees)
* @(#)
* @(#) Usage
* @(#) int im_compass( in, out, m )
* @(#) IMAGE *in, *out;
* @(#) INTMASK *m;
* @(#)
* @(#) Returns 0 on sucess and -1 on error
* @(#)
* @(#) Returns an int pointer to valid offsets for rotating a square mask
* @(#) of odd size by 45 degrees.
* @(#)
* @(#) Usage
* @(#) int *im_offsets45( size )
* @(#) int size;
* @(#)
* @(#) Returns an int pointer to valid offsets on sucess and -1 on error
* @(#)
/* im_compass
*
* Author: N. Dessipris (Copyright, N. Dessipris 1991)
* Written on: 08/05/1991
* Modified on:
* 11/3/01 JC
* - rewritten, calling im_conv() and im_maxvalue()
* 3/2/10
* - gtkdoc
*/
/*
@ -67,6 +51,20 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/**
* im_compass:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* @in is convolved 8 times with @mask, each time @mask is rotated by 45
* degrees. Each output pixel is the largest absolute value of the 8
* convolutions.
*
* See also: im_lindetect(), im_gradient(), im_conv().
*
* Returns: 0 on success, -1 on error
*/
int
im_compass( IMAGE *in, IMAGE *out, INTMASK *mask )
{
@ -94,6 +92,20 @@ im_compass( IMAGE *in, IMAGE *out, INTMASK *mask )
return( im_maxvalue( absed, out, 8 ) );
}
/**
* im_lindetect:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* @in is convolved four times with @mask, each time @mask is rotated by 45
* degrees. Each output pixel is the largest absolute value of the four
* convolutions.
*
* See also: im_compass(), im_gradient(), im_conv().
*
* Returns: 0 on success, -1 on error
*/
int
im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
{
@ -121,15 +133,26 @@ im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
return( im_maxvalue( absed, out, 4 ) );
}
#define GTEMPS (4)
/**
* im_gradient:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* @in is convolved with @mask and with @mask after a 90 degree rotation. The
* result is the sum of the absolute value of the two convolutions.
*
* See also: im_lindetect(), im_gradient(), im_conv().
*
* Returns: 0 on success, -1 on error
*/
int
im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
{
IMAGE *t[GTEMPS];
IMAGE *t[4];
INTMASK *rmask;
if( im_open_local_array( out, t, GTEMPS, "im_gradient", "p" ) )
if( im_open_local_array( out, t, 4, "im_gradient", "p" ) )
return( -1 );
if( !(rmask = (INTMASK *) im_local( out,

View File

@ -1,27 +1,4 @@
/* @(#) Generate an image where the value of each pixel represents the
* @(#) contrast within a window of half_win_size from the corresponsing
* @(#) point in the input image. Sub-sample by a factor of spacing.
* @(#)
* @(#) Pixels beyond the edges of the image are considered to be have the
* @(#) value zero (black).
* @(#)
* @(#) Input must be single-band uncoded uchar, WIO or PIO.
* @(#)
* @(#) Output is single-band uncoded uint, WIO or PIO.
* @(#)
* @(#) int
* @(#) im_contrast_surface(
* @(#) IMAGE *in,
* @(#) IMAGE *out,
* @(#) int half_win_size,
* @(#) int spacing
* @(#) );
* @(#)
* @(#) Returns either 0 (success) or -1 (fail)
* @(#)
* @(#) Also: im_contrast_surface_raw(). As above, but pixels within
* @(#) half_win_size of the edge are not calculated, and output is smaller
* @(#) accordingly.
/* im_contrast_surface
*
* Copyright: 2006, The Nottingham Trent University
*
@ -29,6 +6,9 @@
* (based on algorithm by Nicos Dessipris & John Cupitt)
*
* Written on: 2006-03-13
* 3/2/10
* - gtkdoc
* - small cleanups
*/
/*
@ -111,6 +91,21 @@ static unsigned int calc_cont (REGION * reg, int win_size_less_one,
/** EXPORTED FUNCTIONS **/
/**
* im_contrast_surface:
* @in: input image
* @out: output image
* @half_win_size: window radius
* @spacing: subsample output by this
*
* Generate an image where the value of each pixel represents the
* contrast within a window of half_win_size from the corresponsing
* point in the input image. Sub-sample by a factor of spacing.
*
* See also: im_spcor(), im_gradcor().
*
* Returns: 0 on success, -1 on error.
*/
int
im_contrast_surface (IMAGE * in, IMAGE * out, int half_win_size, int spacing)
{
@ -138,16 +133,12 @@ im_contrast_surface_raw (IMAGE * in, IMAGE * out, int half_win_size,
cont_surf_params_t *params;
if (im_piocheck (in, out))
if (im_piocheck (in, out) ||
im_check_uncoded (FUNCTION_NAME, in) ||
im_check_mono (FUNCTION_NAME, in) ||
im_check_format (FUNCTION_NAME, in, IM_BANDFMT_UCHAR))
return -1;
if (IM_CODING_NONE != in->Coding || IM_BANDFMT_UCHAR != in->BandFmt
|| 1 != in->Bands)
{
im_error (FUNCTION_NAME, "%s", _("one band uncoded uchar only"));
return -1;
}
if (half_win_size < 1 || spacing < 1)
{
im_error (FUNCTION_NAME, "%s", _("bad parameters"));

View File

@ -1,27 +1,4 @@
/* @(#) Convolve an image with an INTMASK. Image can have any number of bands,
* @(#) any non-complex type. Size and type of output image matches type of
* @(#) input image.
* @(#)
* @(#) int
* @(#) im_conv( in, out, mask )
* @(#) IMAGE *in, *out;
* @(#) INTMASK *mask;
* @(#)
* @(#) Also: im_conv_raw(). As above, but does not add a black border.
* @(#)
* @(#) Returns either 0 (success) or -1 (fail)
* @(#)
* @(#) Old code, kept for use of other old code in this package:
* @(#)
* @(#) Creates int luts for all non zero elm of the original mask;
* @(#) which is kept in buffer of length buffersize
* @(#) cnt is needed for freeing luts. Called by the above.
* @(#)
* @(#) int im__create_int_luts( buffer, buffersize, orig_luts, luts, cnt )
* @(#) int *buffer, buffersize;
* @(#) int **orig_luts, **luts, *cnt;
* @(#)
* @(#) Returns either 0 (sucess) or -1 (fail)
/* im_conv
*
* Copyright: 1990, N. Dessipris.
*
@ -71,6 +48,9 @@
* - only check for non-zero elements once
* - add mask-all-zero check
* - cleanups
* 3/2/10
* - gtkdoc
* - more cleanups
*/
/*
@ -285,7 +265,7 @@ conv_start( IMAGE *out, void *a, void *b )
i += 1; \
}
/* INT and FLOAT inner loops.
/* INT inner loops.
*/
#define CONV_INT( TYPE, IM_CLIP ) { \
TYPE ** restrict p = (TYPE **) seq->pts; \
@ -307,6 +287,8 @@ conv_start( IMAGE *out, void *a, void *b )
} \
}
/* FLOAT inner loops.
*/
#define CONV_FLOAT( TYPE ) { \
TYPE ** restrict p = (TYPE **) seq->pts; \
TYPE * restrict q = (TYPE *) IM_REGION_ADDR( or, le, y ); \
@ -434,14 +416,9 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
*/
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_conv", in ) ||
im_check_noncomplex( "im_conv", in ) )
im_check_noncomplex( "im_conv", in ) ||
im_check_imask( "im_conv", mask ) )
return( -1 );
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
mask->scale == 0 ) {
im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
return( -1 );
}
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@ -460,10 +437,8 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
return( -1 );
if( im_generate( out, conv_start, conv_gen, conv_stop, in, conv ) )
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ||
im_generate( out, conv_start, conv_gen, conv_stop, in, conv ) )
return( -1 );
out->Xoffset = -mask->xsize / 2;
@ -472,7 +447,24 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
return( 0 );
}
/* The above, with a border to make out the same size as in.
/**
* im_conv:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* Convolve @in with @mask using integer arithmetic. The output image
* always has the same #VipsBandFmt as the input image. Non-complex images
* only.
*
* Each output pixel is
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
* and offset are part of @mask. For integer @in, the division by scale
* includes round-to-nearest.
*
* See also: im_conv_f(), im_convsep(), im_create_imaskv().
*
* Returns: 0 on success, -1 on error
*/
int
im_conv( IMAGE *in, IMAGE *out, INTMASK *mask )

View File

@ -1,14 +1,4 @@
/* @(#) Convolve an image with a DOUBLEMASK. Image can have any number of bands,
* @(#) any non-complex type. Output is IM_BANDFMT_FLOAT for all non-complex inputs
* @(#) except IM_BANDFMT_DOUBLE, which gives IM_BANDFMT_DOUBLE.
* @(#)
* @(#) int
* @(#) im_conv_f( in, out, mask )
* @(#) IMAGE *in, *out;
* @(#) DOUBLEMASK *mask;
* @(#)
* @(#) Returns either 0 (success) or -1 (fail)
* @(#)
/* im_conv_f
*
* Copyright: 1990, N. Dessipris.
*
@ -43,6 +33,9 @@
* 13/11/09
* - rename as im_conv_f() to make it easier to vips.c to make the
* overloaded version
* 3/2/10
* - gtkdoc
* - more cleanups
*/
/*
@ -320,14 +313,9 @@ im_conv_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
*/
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_conv", in ) ||
im_check_noncomplex( "im_conv", in ) )
im_check_noncomplex( "im_conv", in ) ||
im_check_dmask( "im_conv", mask ) )
return( -1 );
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
mask->scale == 0 ) {
im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
return( -1 );
}
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@ -360,7 +348,24 @@ im_conv_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
return( 0 );
}
/* The above, with a border to make out the same size as in.
/**
* im_conv_f:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* Convolve @in with @mask using floating-point arithmetic. The output image
* is always %IM_BANDFMT_FLOAT unless @in is %IM_BANDFMT_DOUBLE, in which case
* @out is also %IM_BANDFMT_DOUBLE. Non-complex images
* only.
*
* Each output pixel is
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
* and offset are part of @mask.
*
* See also: im_conv(), im_convsep_f(), im_create_dmaskv().
*
* Returns: 0 on success, -1 on error
*/
int
im_conv_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )

View File

@ -1,15 +1,4 @@
/* @(#) Convolve an image with a seperable (1xN, or Nx1) INTMASK. Image can
* @(#) have any number of bands, any non-complex type. Size and type of
* @(#) output image matches type of input image.
* @(#)
* @(#) int
* @(#) im_convsep( in, out, mask )
* @(#) IMAGE *in, *out;
* @(#) INTMASK *mask;
* @(#)
* @(#) Also: im_convsep_raw(). As above, but does not add a black border.
* @(#)
* @(#) Returns either 0 (success) or -1 (fail)
/* im_convsep
*
* Copyright: 1990, N. Dessipris.
*
@ -29,6 +18,9 @@
* overflow on intermediates
* 12/5/08
* - int rounding was +1 too much, argh
* 3/2/10
* - gtkdoc
* - more cleanups
*/
/*
@ -379,24 +371,16 @@ im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
/* Check parameters.
*/
if( !in || in->Coding != IM_CODING_NONE ||
vips_bandfmt_iscomplex( in->BandFmt ) ) {
im_error( "im_convsep", "%s", _( "non-complex uncoded only" ) );
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_convsep", in ) ||
im_check_noncomplex( "im_convsep", in ) ||
im_check_imask( "im_convsep", mask ) )
return( -1 );
}
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
mask->scale == 0 ) {
im_error( "im_convsep", "%s", _( "nonsense mask parameters" ) );
return( -1 );
}
if( mask->xsize != 1 && mask->ysize != 1 ) {
im_error( "im_convsep",
"%s", _( "expect 1xN or Nx1 input mask" ) );
return( -1 );
}
if( im_piocheck( in, out ) )
return( -1 );
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@ -424,7 +408,32 @@ im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
return( 0 );
}
/* The above, with a border to make out the same size as in.
/**
* im_convsep:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* Perform a separable convolution of @in with @mask using integer arithmetic.
*
* The mask must be 1xn or nx1 elements.
* The output image
* always has the same #VipsBandFmt as the input image. Non-complex images
* only.
*
* The image is convolved twice: once with @mask and then again with @mask
* rotated by 90 degrees. This is much faster for certain types of mask
* (gaussian blur, for example) than doing a full 2D convolution.
*
* Each output pixel is
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
* and offset are part of @mask. For integer @in, the division by scale
* includes round-to-nearest.
*
* See also: im_convsep_f(), im_conv(), im_create_imaskv().
*
* Returns: 0 on success, -1 on error
*/
int
im_convsep( IMAGE *in, IMAGE *out, INTMASK *mask )

View File

@ -1,14 +1,4 @@
/* @(#) Convolve an image with a DOUBLEMASK. Image can have any number of bands,
* @(#) any non-complex type. Output is IM_BANDFMT_FLOAT for all non-complex inputs
* @(#) except IM_BANDFMT_DOUBLE, which gives IM_BANDFMT_DOUBLE.
* @(#) Separable mask of sizes 1xN or Nx1
* @(#)
* @(#) int im_convsep_f( in, out, mask )
* @(#) IMAGE *in, *out;
* @(#) DOUBLEMASK *mask; details in mask.h
* @(#)
* @(#) Returns either 0 (sucess) or -1 (fail)
* @(#) Picture can have any number of channels (max 64).
/* im_convsep_f
*
* Copyright: 1990, N. Dessipris.
*
@ -21,6 +11,9 @@
* - now uses im_embed() with edge stretching on the input, not
* the output
* - sets Xoffset / Yoffset
* 3/2/10
* - gtkdoc
* - more cleanups
*/
/*
@ -81,10 +74,7 @@ typedef struct {
static int
conv_destroy( Conv *conv )
{
if( conv->mask ) {
(void) im_free_dmask( conv->mask );
conv->mask = NULL;
}
IM_FREEF( im_free_dmask, conv->mask );
return( 0 );
}
@ -285,26 +275,16 @@ im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
/* Check parameters.
*/
if( !in ||
in->Coding != IM_CODING_NONE ||
vips_bandfmt_iscomplex( in->BandFmt ) ) {
im_error( "im_convsep_f",
"%s", _( "non-complex uncoded only" ) );
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_convsep_f", in ) ||
im_check_noncomplex( "im_convsep_f", in ) ||
im_check_dmask( "im_convsep_f", mask ) )
return( -1 );
}
if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
mask->scale == 0 ) {
im_error( "im_convsep_f", "%s", _( "bad mask parameters" ) );
return( -1 );
}
if( mask->xsize != 1 && mask->ysize != 1 ) {
im_error( "im_convsep_f",
"%s", _( "expect 1xN or Nx1 input mask" ) );
return( -1 );
}
if( im_piocheck( in, out ) )
return( -1 );
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@ -335,7 +315,32 @@ im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
return( 0 );
}
/* The above, with a border to make out the same size as in.
/**
* im_convsep_f:
* @in: input image
* @out: output image
* @mask: convolution mask
*
* Perform a separable convolution of @in with @mask using floating-point
* arithmetic.
*
* The mask must be 1xn or nx1 elements.
* The output image
* is always %IM_BANDFMT_FLOAT unless @in is %IM_BANDFMT_DOUBLE, in which case
* @out is also %IM_BANDFMT_DOUBLE. Non-complex images
* only.
*
* The image is convolved twice: once with @mask and then again with @mask
* rotated by 90 degrees. This is much faster for certain types of mask
* (gaussian blur, for example) than doing a full 2D convolution.
*
* Each output pixel is
* calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
* and offset are part of @mask.
*
* See also: im_convsep(), im_conv(), im_create_dmaskv().
*
* Returns: 0 on success, -1 on error
*/
int
im_convsep_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )

View File

@ -1,19 +1,4 @@
/* @(#) Functions which calculates spatial correlation between two images.
* @(#) by taking absolute differences pixel by pixel without calculating
* @(#) the correlation coefficient.
* @(#)
* @(#) The function works as follows:
* @(#)
* @(#) int im_fastcor( im, ref, out )
* @(#) IMAGE *im, *ref, *out;
* @(#)
* @(#) ref must be smaller than in. The correlation is
* @(#) calculated by overlaping im on the top left corner of ref
* @(#) and moving it all over ref calculating the correlation coefficient
* @(#) at each point. The resultant coefficients are written as unsigned int
* @(#) numbers in out which has the size of im.
* @(#)
* @(#) Returns 0 on sucess and -1 on error.
/* im_fastcor
*
* Copyright: 1990, N. Dessipris.
*
@ -34,6 +19,9 @@
* - use im_embed() with edge stretching on the input, not the output
* - calculate sum of squares of differences, rather than abs of
* difference
* 3/2/10
* - gtkdoc
* - cleanups
*/
/*
@ -142,7 +130,8 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
{
/* PIO between in and out; WIO from ref.
*/
if( im_piocheck( in, out ) || im_incheck( ref ) )
if( im_piocheck( in, out ) ||
im_incheck( ref ) )
return( -1 );
/* Check sizes.
@ -154,14 +143,13 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
/* Check types.
*/
if( in->Coding != IM_CODING_NONE || in->Bands != 1 ||
in->BandFmt != IM_BANDFMT_UCHAR ||
ref->Coding != IM_CODING_NONE || ref->Bands != 1 ||
ref->BandFmt != IM_BANDFMT_UCHAR ) {
im_error( "im_fastcor_raw", "%s",
_( "input not uncoded 1 band uchar" ) );
if( im_check_uncoded( "im_fastcor", in ) ||
im_check_format( "im_fastcor", in, IM_BANDFMT_UCHAR ) ||
im_check_mono( "im_fastcor", in ) ||
im_check_uncoded( "im_fastcor", ref ) ||
im_check_format( "im_fastcor", ref, IM_BANDFMT_UCHAR ) ||
im_check_mono( "im_fastcor", ref ) )
return( -1 );
}
/* Prepare the output image.
*/
@ -171,16 +159,12 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
out->Xsize = in->Xsize - ref->Xsize + 1;
out->Ysize = in->Ysize - ref->Ysize + 1;
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
/* FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
return( -1 );
/* Write the correlation.
*/
if( im_generate( out,
im_start_one, fastcor_gen, im_stop_one, in, ref ) )
if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ||
im_generate( out,
im_start_one, fastcor_gen, im_stop_one, in, ref ) )
return( -1 );
out->Xoffset = -ref->Xsize / 2;
@ -189,7 +173,22 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
return( 0 );
}
/* The above, with a border to make out the same size as in.
/**
* im_fastcor:
* @in: input image
* @ref: reference image
* @out: output image
*
* Calculate a fast correlation surface.
*
* @ref is placed at every position in @in and the sum of squares of
* differences calculated. One-band, 8-bit unsigned images only. The output
* image is always %IM_BANDFMT_UINT. @ref must be smaller than @in. The output
* image is the same size as the input.
*
* See also: im_spcor().
*
* Returns: 0 on success, -1 on error
*/
int
im_fastcor( IMAGE *in, IMAGE *ref, IMAGE *out )

View File

@ -1,23 +1,12 @@
/* @(#) Like im_spcor(), but with a new metric.
* @(#)
* @(#) takes the gradient images of the two images, and takes the dot-product
* @(#) correlation of the two vector images.
* @(#)
* @(#) (vector images are never really used, the two components are
* @(#) calculated separately)
* @(#)
* @(#) The vector expression of this method is my (tcv) own creation. It is
* @(#) equivalent to the complex-number method of:
* @(#)
* @(#) ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using
* @(#) gradient cross correlation. Electronics Letters, 39 (13).
* @(#)
* @(#) It's suitability for sub-pixel alignment is not (yet) tested.
/* im_gradcor
*
* Copyright: 2007 Nottingham Trent University
*
* Author: Tom Vajzovic
* Written on: 2007-06-07
* 3/2/10
* - gtkdoc
* - cleanups
*/
/*
@ -112,19 +101,14 @@ int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){
if( im_piocheck( large, out ) || im_pincheck( small ) )
return -1;
if( ! vips_bandfmt_isint( large->BandFmt ) ||
! vips_bandfmt_isint( small->BandFmt ) ){
im_error( FUNCTION_NAME, "image does not have integer band format" );
return -1;
}
if( large-> Coding || small-> Coding ){
im_error( FUNCTION_NAME, "image is not uncoded" );
return -1;
}
if( 1 != large-> Bands || 1 != small-> Bands ){
im_error( FUNCTION_NAME, "image is multi-band" );
return -1;
}
if( im_check_uncoded( "im_gradcor", large ) ||
im_check_mono( "im_gradcor", large ) ||
im_check_uncoded( "im_gradcor", small ) ||
im_check_mono( "im_gradcor", small ) ||
im_check_format_same( "im_gradcor", large, small ) ||
im_check_int( "im_gradcor", large ) )
return( -1 );
if( large-> Xsize < small-> Xsize || large-> Ysize < small-> Ysize ){
im_error( FUNCTION_NAME, "second image must be smaller than first" );
return -1;
@ -152,6 +136,32 @@ int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){
#undef FUNCTION_NAME
}
/**
* im_gradcor:
* @in: input image
* @ref: reference image
* @out: output image
*
* Calculate a correlation surface.
*
* @ref is placed at every position in @in and a correlation coefficient
* calculated. One-band, integer images only. @in and @ref must have the
* same #VipsBandFmt. The output
* image is always %IM_BANDFMT_FLOAT. @ref must be smaller than @in. The output
* image is the same size as the input.
*
* The method takes the gradient images of the two images then takes the
* dot-product correlation of the two vector images.
* The vector expression of this method is my (tcv) own creation. It is
* equivalent to the complex-number method of:
*
* ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using
* gradient cross correlation. Electronics Letters, 39 (13).
*
* See also: im_spcor().
*
* Returns: 0 on success, -1 on error
*/
int
im_gradcor( IMAGE *in, IMAGE *ref, IMAGE *out )
{
@ -173,24 +183,35 @@ im_gradcor( IMAGE *in, IMAGE *ref, IMAGE *out )
#undef FUNCTION_NAME
}
/**
* im_grad_x:
* @in: input image
* @out: output image
*
* Find horizontal differences between adjacent pixels.
*
* Generates an image where the value of each pixel is the difference between
* it and the pixel to its right. The output has the same height as the input
* and one pixel less width. One-band integer formats only. The result is
* always %IM_BANDFMT_INT.
*
* This operation is much faster than (though equivalent to) im_conv() with the
* mask [[-1, 1]].
*
* See also: im_grad_y(), im_conv().
*
* Returns: 0 on success, -1 on error
*/
int im_grad_x( IMAGE *in, IMAGE *out ){
#define FUNCTION_NAME "im_grad_x"
if( im_piocheck( in, out ) )
return -1;
if( ! vips_bandfmt_isint( in->BandFmt ) ){
im_error( FUNCTION_NAME, "image does not have integer band format" );
return -1;
}
if( in-> Coding ){
im_error( FUNCTION_NAME, "image is not uncoded" );
return -1;
}
if( 1 != in-> Bands ){
im_error( FUNCTION_NAME, "image is multi-band" );
return -1;
}
if( im_check_uncoded( "im_grad_x", in ) ||
im_check_mono( "im_grad_x", in ) ||
im_check_int( "im_grad_x", in ) )
return( -1 );
if( im_cp_desc( out, in ) )
return -1;
@ -238,24 +259,37 @@ int im_grad_x( IMAGE *in, IMAGE *out ){
#undef FUNCTION_NAME
}
/**
* im_grad_y:
* @in: input image
* @out: output image
*
* Find vertical differences between adjacent pixels.
*
* Generates an image where the value of each pixel is the difference between
* it and the pixel below it. The output has the same width as the input
* and one pixel less height. One-band integer formats only. The result is
* always %IM_BANDFMT_INT.
*
* This operation is much faster than (though equivalent to) im_conv() with the
* mask [[-1], [1]].
*
* See also: im_grad_x(), im_conv().
*
* Returns: 0 on success, -1 on error
*/
int im_grad_y( IMAGE *in, IMAGE *out ){
#define FUNCTION_NAME "im_grad_y"
if( im_piocheck( in, out ) )
return -1;
if( ! vips_bandfmt_isint( in->BandFmt ) ){
im_error( FUNCTION_NAME, "image does not have integer band format" );
return -1;
}
if( in-> Coding ){
im_error( FUNCTION_NAME, "image is not uncoded" );
return -1;
}
if( 1 != in-> Bands ){
im_error( FUNCTION_NAME, "image is multi-band" );
return -1;
}
if( im_check_uncoded( "im_grad_y", in ) ||
im_check_mono( "im_grad_y", in ) ||
im_check_int( "im_grad_y", in ) )
return( -1 );
if( im_cp_desc( out, in ) )
return -1;

View File

@ -36,6 +36,9 @@
* - ~15% speed up in total
* 29/11/06
* - convolve first to help region sharing
* 3/2/10
* - gtkdoc
* - cleanups
*/
/*
@ -212,6 +215,73 @@ sharpen_mask_new( int radius )
return( line );
}
/**
* im_sharpen:
* @in: input image
* @out: output image
* @mask_size: how large a mask to use
* @x1: flat/jaggy threshold
* @y2: maximum amount of brightening
* @y3: maximum amount of darkening
* @m1: slope for flat areas
* @m2: slope for jaggy areas
*
* Selectively sharpen the L channel of a LAB image. Works for %IM_CODING_LABQ
* and LABS images.
*
* The operation performs a gaussian blur of size @mask_size and subtracts
* from @in to
* generate a high-frequency signal. This signal is passed through a lookup
* table formed from the five parameters and added back to @in.
*
* The lookup table is formed like this:
*
* |[
^
y2 |- - - - - -----------
| /
| / slope m2
| .../
-x1 | ... |
-------------------...---------------------->
| ... | x1
|... slope m1
/ |
/ m2 |
/ |
/ |
/ |
/ |
______/ _ _ _ _ _ _ | -y3
|
* ]|
*
* For printing, we recommend the following settings:
*
* |[
mask_size == 7
x1 == 1.5
y2 == 20 (don't brighten by more than 20 L*)
y3 == 50 (can darken by up to 50 L*)
m1 == 1 (some sharpening in flat areas)
m2 == 2 (more sharpening in jaggy areas)
* ]|
*
* If you want more or less sharpening, we suggest you just change the m1
* and m2 parameters.
*
* The @mask_size parameter changes the width of the fringe and can be
* adjusted according to the output printing resolution. As an approximate
* guideline, use 3 for 4 pixels/mm (CRT display resolution), 5 for 8
* pixels/mm, 7 for 12 pixels/mm and 9 for 16 pixels/mm (300 dpi == 12
* pixels/mm). These figures refer to the image raster, not the half-tone
* resolution.
*
* See also: im_conv().
*
* Returns: 0 on success, -1 on error.
*/
int
im_sharpen( IMAGE *in, IMAGE *out,
int mask_size,
@ -243,20 +313,19 @@ im_sharpen( IMAGE *in, IMAGE *out,
/* Check IMAGE parameters
*/
if( in->Coding != IM_CODING_NONE ||
in->Bands != 3 ||
in->BandFmt != IM_BANDFMT_SHORT ) {
im_error( "im_sharpen", "%s", _( "input not 3-band short" ) );
return( -1 );
}
if( im_piocheck( in, out ) )
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_sharpen", in ) ||
im_check_bands( "im_gradcor", in, 3 ) ||
im_check_format( "im_gradcor", in, IM_BANDFMT_SHORT ) )
return( -1 );
/* Check number range.
*/
if( x1 < 0 || x2 < 0 || x1 > 99 || x2 > 99 || x1 > x2 ||
x3 < 0 || x3 > 99 || x1 > x3 ) {
if( x1 < 0 || x1 > 99 ||
x2 < 0 || x2 > 99 ||
x1 > x2 ||
x3 < 0 || x3 > 99 ||
x1 > x3 ) {
im_error( "im_sharpen", "%s", _( "parameters out of range" ) );
return( -1 );
}

View File

@ -1,21 +1,4 @@
/* @(#) Functions which calculates the correlation coefficient between two
* @(#) images.
* @(#)
* @(#) int im_spcor( IMAGE *in, IMAGE *ref, IMAGE *out )
* @(#)
* @(#) We calculate:
* @(#)
* @(#) sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
* @(#) c(k,l) = ------------------------------------------------
* @(#) sqrt(sumij (ref(i,j)-mean(ref))^2) *
* @(#) sqrt(sumij (inkl(i,j)-mean(inkl))^2)
* @(#)
* @(#) where inkl is the area of in centred at position (k,l).
* @(#)
* @(#) Writes float to out. in and ref must be 1 band uchar, or 1 band
* @(#) ushort.
* @(#)
* @(#) Returns 0 on sucess and -1 on error.
/* im_spcor
*
* Copyright: 1990, N. Dessipris; 2006, 2007 Nottingham Trent University.
*
@ -48,6 +31,9 @@
* - make im_spcor a wrapper selecting either im__spcor or im__spcor2
* 2008-09-09 JC
* - roll back the windowed version for now, it has some tile edge effects
* 3/2/10
* - gtkdoc
* - cleanups
*/
/*
@ -185,14 +171,11 @@ spcor_gen( REGION *or, void *vseq, void *a, void *b )
*/
switch( ref->BandFmt ) {
case IM_BANDFMT_UCHAR: LOOP(unsigned char); break;
case IM_BANDFMT_CHAR: LOOP(signed char); break;
case IM_BANDFMT_USHORT: LOOP(unsigned short); break;
case IM_BANDFMT_SHORT: LOOP(signed short); break;
default:
error_exit( "im_spcor: internal error #7934" );
/* Keep gcc -Wall happy.
*/
return( -1 );
g_assert( 0 );
}
/* Now: calculate correlation coefficient!
@ -260,20 +243,17 @@ im_spcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
/* Check types.
*/
if( in->Coding != IM_CODING_NONE ||
in->Bands != 1 ||
ref->Coding != IM_CODING_NONE ||
ref->Bands != 1 ||
in->BandFmt != ref->BandFmt ) {
im_error( "im_spcor_raw",
"%s", _( "input not uncoded 1 band" ) );
if( im_check_uncoded( "im_spcor", in ) ||
im_check_mono( "im_spcor", in ) ||
im_check_uncoded( "im_spcor", ref ) ||
im_check_mono( "im_spcor", ref ) ||
im_check_format_same( "im_spcor", in, ref ) )
return( -1 );
}
if( in->BandFmt != IM_BANDFMT_UCHAR &&
in->BandFmt != IM_BANDFMT_CHAR &&
in->BandFmt != IM_BANDFMT_SHORT &&
in->BandFmt != IM_BANDFMT_USHORT ) {
im_error( "im_spcor_raw",
im_error( "im_spcor",
"%s", _( "input not char/uchar/short/ushort" ) );
return( -1 );
}
@ -309,7 +289,37 @@ im_spcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
return( 0 );
}
/* The above, with the input expanded to make out the same size as in.
/**
* im_spcor:
* @in: input image
* @ref: reference image
* @out: output image
*
* Calculate a correlation surface.
*
* @ref is placed at every position in @in and the correlation coefficient
* calculated. One-band, 8 or 16-bit images only. @in and @ref must have the
* same #VipsBandFmt. The output
* image is always %IM_BANDFMT_FLOAT. @ref must be smaller than @in. The output
* image is the same size as the input.
*
* The correlation coefficient is calculated as:
*
* |[
* sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
* c(k,l) = ------------------------------------------------
* sqrt(sumij (ref(i,j)-mean(ref))^2) *
* sqrt(sumij (inkl(i,j)-mean(inkl))^2)
* ]|
*
* where inkl is the area of @in centred at position (k,l).
*
* from Niblack "An Introduction to Digital Image Processing",
* Prentice/Hall, pp 138.
*
* See also: im_gradcor(), im_fastcor().
*
* Returns: 0 on success, -1 on error
*/
int
im_spcor( IMAGE *in, IMAGE *ref, IMAGE *out )

View File

@ -59,6 +59,8 @@ int im_check_u8or16( const char *domain, IMAGE *im );
int im_check_format_same( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_size_same( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_vector( const char *domain, int n, IMAGE *im );
int im_check_imask( const char *domain, INTMASK *mask );
int im_check_dmask( const char *domain, DOUBLEMASK *mask );
gboolean vips_bandfmt_isint( VipsBandFmt fmt );
gboolean vips_bandfmt_isuint( VipsBandFmt fmt );

View File

@ -919,6 +919,60 @@ im_check_vector( const char *domain, int n, IMAGE *im )
return( 0 );
}
/**
* im_check_imask:
* @domain: the originating domain for the error message
* @mask: mask to check
*
* Sanity-check a mask parameter.
*
* See also: im_error().
*
* Returns: 0 if OK, -1 otherwise.
*/
int
im_check_imask( const char *domain, INTMASK *mask )
{
if( !mask ||
mask->xsize > 1000 ||
mask->ysize > 1000 ||
mask->xsize <= 0 ||
mask->ysize <= 0 ||
!mask->coeff ) {
im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
return( -1 );
}
return( 0 );
}
/**
* im_check_dmask:
* @domain: the originating domain for the error message
* @mask: mask to check
*
* Sanity-check a mask parameter.
*
* See also: im_error().
*
* Returns: 0 if OK, -1 otherwise.
*/
int
im_check_dmask( const char *domain, DOUBLEMASK *mask )
{
if( !mask ||
mask->xsize > 1000 ||
mask->ysize > 1000 ||
mask->xsize <= 0 ||
mask->ysize <= 0 ||
!mask->coeff ) {
im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
return( -1 );
}
return( 0 );
}
/**
* vips_bandfmt_isint:
* @fmt: format to test