Пример #1
0
/* Try to open a file. If full path fails, try the current directory.
 */
IMAGE *
im__global_open_image( SymbolTable *st, char *name )
{
	IMAGE *im;

	if( (im = im_open_local( st->im, name, "r" )) ) 
		return( im );
	if( (im = im_open_local( st->im, im_skip_dir( name ), "r" )) ) 
		return( im );

	return( NULL );
}
Пример #2
0
/* Morph an image.
 */
int
im_lab_morph( IMAGE *in, IMAGE *out,
	DOUBLEMASK *mask, 
	double L_offset, double L_scale, 
	double a_scale, double b_scale )
{
	Params *parm;

        /* Recurse for coded images.
         */
	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t1 = im_open_local( out, "im_lab_morph:1", "p" );
		IMAGE *t2 = im_open_local( out, "im_lab_morph:2", "p" );

		if( !t1 || !t2 ||
			im_LabQ2Lab( in, t1 ) ||
			im_lab_morph( t1, t2, 
				mask, L_offset, L_scale, a_scale, b_scale ) ||
			im_Lab2LabQ( t2, out ) )
			return( -1 );

		return( 0 );
	}

        if( in->Coding != IM_CODING_NONE ) {
		im_errormsg( "im_lab_morph: must be uncoded or IM_CODING_LABQ" ); 
		return( -1 );
	}
	if( in->BandFmt != IM_BANDFMT_FLOAT && in->BandFmt != IM_BANDFMT_DOUBLE ) {
		im_errormsg( "im_lab_morph: must be uncoded float or double" );
		return( -1 );
	}
	if( in->Bands != 3 ) {
		im_errormsg( "im_lab_morph: must be 3 bands" ); 
		return( -1 );
	}

	if( !(parm = IM_NEW( out, Params )) ||
		morph_init( parm,
			in, out, L_scale, L_offset, mask, a_scale, b_scale ) ) 
		return( -1 );

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = IM_TYPE_LAB;

	if( im_wrapone( in, out, 
		(im_wrapone_fn) morph_buffer, parm, NULL ) )
		return( -1 );

        return( 0 );
}
Пример #3
0
int 
im_freqflt( IMAGE *in, IMAGE *mask, IMAGE *out )
{
	IMAGE *dummy;

	/* Placeholder for memory free.
	 */
	if( !(dummy = im_open( "memory-1", "p" )) )
		return( -1 );

	if( im_iscomplex( in ) ) {
		/* Easy case! Assume it has already been transformed.
		 */
		IMAGE *t1 = im_open_local( dummy, "im_freqflt-1", "p" );

		if( !t1 ||
			im_multiply( in, mask, t1 ) ||
			im_invfftr( t1, out ) ) {
			im_close( dummy );
			return( -1 );
		}
	}
	else {
		/* Harder - fft first, then mult, then force back to start
		 * type.
		 * 
		 * Optimisation: output of im_invfft() is float buffer, we 
		 * will usually chagetype to char, so rather than keeping a
		 * large float buffer and partial to char from that, do
		 * changetype to a memory buffer, and copy to out from that.
		 */
		IMAGE *t[3];
		IMAGE *t3;

		if( im_open_local_array( dummy, t, 3, "im_freqflt-1", "p" ) ||
			!(t3 = im_open_local( out, "im_freqflt-3", "t" )) ||
			im_fwfft( in, t[0] ) ||
			im_multiply( t[0], mask, t[1] ) ||
			im_invfftr( t[1], t[2] ) ||
			im_clip2fmt( t[2], t3, in->BandFmt ) ||
			im_copy( t3, out ) ) {
			im_close( dummy );
			return( -1 );
		}	
	}

	im_close( dummy );

	return( 0 );
}
Пример #4
0
/* Normalise an image using the rules noted above.
 */
static int
normalise( IMAGE *in, IMAGE *out )
{
	if( im_check_uncoded( "im_histplot", in ) ||
		im_check_noncomplex( "im_histplot", in ) )
		return( -1 );

	if( vips_bandfmt_isuint( in->BandFmt ) ) {
		if( im_copy( in, out ) )
			return( -1 );
	}
	else if( vips_bandfmt_isint( in->BandFmt ) ) {
		IMAGE *t1;
		double min;

		/* Move min up to 0. 
		 */
		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_min( in, &min ) ||
			im_lintra( 1.0, in, -min, t1 ) )
			return( -1 );
	}
	else {
		/* Float image: scale min--max to 0--any. Output square
		 * graph.
		 */
		IMAGE *t1;
		DOUBLEMASK *stats;
		double min, max;
		int any;

		if( in->Xsize == 1 )
			any = in->Ysize;
		else
			any = in->Xsize;

		if( !(stats = im_stats( in )) )
			return( -1 );
		min = VIPS_MASK( stats, 0, 0 );
		max = VIPS_MASK( stats, 1, 0 );
		im_free_dmask( stats );

		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_lintra( any / (max - min), in, 
				-min * any / (max - min), out ) )
			return( -1 );
	}

	return( 0 );
}
Пример #5
0
int 
im_heq( IMAGE *in, IMAGE *out, int bandno )
{
	IMAGE *t1 = im_open_local( out, "im_heq:1", "p" );
	IMAGE *t2 = im_open_local( out, "im_heq:2", "p" );

	if( !t1 || !t2 ||
		im_histgr( in, t1, bandno ) ||
		im_histeq( t1, t2 ) ||
		im_maplut( in, out, t2 ) )
		return( -1 );

	return( 0 );
}
Пример #6
0
/* As above, but make a IM_BANDFMT_UCHAR image.
 */
int
im_zone( IMAGE *im, int size )
{
	IMAGE *t1 = im_open_local( im, "im_zone:1", "p" );
	IMAGE *t2 = im_open_local( im, "im_zone:2", "p" );

	if( !t1 || !t2 )
		return( -1 );
	
	if( im_fzone( t1, size ) || 
		im_lintra( 127.5, t1, 127.5, t2 ) ||
		im_clip2fmt( t2, im, IM_BANDFMT_UCHAR ) )
		return( -1 );

	return( 0 );
}
Пример #7
0
/* Find the stats for an overlap struct.
 */
static int
find_overlap_stats( OverlapInfo *lap )
{
	IMAGE *t1 = im_open_local( lap->node->im, "find_overlap_stats:1", "p" );
	Rect rarea, sarea;

	/* Translate the overlap area into the coordinate scheme for the main
	 * node.
	 */
	rarea = lap->overlap;
	rarea.left -= lap->node->cumtrn.oarea.left;
	rarea.top -= lap->node->cumtrn.oarea.top;

	/* Translate the overlap area into the coordinate scheme for the other
	 * node.
	 */
	sarea = lap->overlap;
	sarea.left -= lap->other->cumtrn.oarea.left;
	sarea.top -= lap->other->cumtrn.oarea.top;

	/* Make a mask for the overlap.
	 */
	if( make_overlap_mask( lap->node->trnim, lap->other->trnim, t1,
		&rarea, &sarea ) )
		return( -1 );

	/* Find stats for that area.
	 */
	if( !(lap->nstats = find_image_stats( lap->node->trnim, t1, &rarea )) )
		return( -1 );
	if( !(lap->ostats = find_image_stats( lap->other->trnim, t1, &sarea )) )
		return( -1 );

	return( 0 );
}
Пример #8
0
/* Transform an n-band image with a 1-band processing function.
 */
int 
im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn )
{
	if( im_pincheck( in ) || im_outcheck( out ) )
                return( -1 );
	
	if( in->Bands == 1 ) {
		if( fn( dummy, in, out ) )
			return( -1 );
	}
	else {
		IMAGE *acc;
		int b;

		for( acc = NULL, b = 0; b < in->Bands; b++ ) {
			IMAGE *t1 = im_open_local( dummy, 
				"fwfftn:1", "p" );
			IMAGE *t2 = im_open_local( dummy, 
				"fwfftn:2", "p" );

			if( !t1 || !t2 || 
				im_extract_band( in, t1, b ) ||
				fn( dummy, t1, t2 ) )
				return( -1 );
			
			if( !acc )
				acc = t2;
			else {
				IMAGE *t3 = im_open_local( dummy, 
					"fwfftn:3", "p" );

				if( !t3 || im_bandjoin( acc, t2, t3 ) )
					return( -1 );

				acc = t3;
			}
		}

		if( im_copy( acc, out ) )
			return( -1 );
	}

	return( 0 );
}
Пример #9
0
/* As above, but do IM_CODING_LABQ too. And embed the input.
 */
static int 
im__affinei( IMAGE *in, IMAGE *out, 
	VipsInterpolate *interpolate, Transformation *trn )
{
	IMAGE *t3 = im_open_local( out, "im_affine:3", "p" );
	const int window_size = 
		vips_interpolate_get_window_size( interpolate );
	const int window_offset = 
		vips_interpolate_get_window_offset( interpolate );
	Transformation trn2;

	/* Add new pixels around the input so we can interpolate at the edges.
	 */
	if( !t3 ||
		im_embed( in, t3, 1, 
			window_offset, window_offset, 
			in->Xsize + window_size, in->Ysize + window_size ) )
		return( -1 );

	/* Set iarea so we know what part of the input we can take.
	 */
	trn2 = *trn;
	trn2.iarea.left += window_offset;
	trn2.iarea.top += window_offset;

#ifdef DEBUG_GEOMETRY
	printf( "im__affinei: %s\n", in->filename );
	im__transform_print( &trn2 );
#endif /*DEBUG_GEOMETRY*/

	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t[2];

		if( im_open_local_array( out, t, 2, "im_affine:2", "p" ) ||
			im_LabQ2LabS( t3, t[0] ) ||
			affinei( t[0], t[1], interpolate, &trn2 ) ||
			im_LabS2LabQ( t[1], out ) )
			return( -1 );
	}
	else if( in->Coding == IM_CODING_NONE ) {
		if( affinei( t3, out, interpolate, &trn2 ) )
			return( -1 );
	}
	else {
		im_error( "im_affinei", "%s", _( "unknown coding type" ) );
		return( -1 );
	}

	/* Finally: can now set Xoffset/Yoffset.
	 */
	out->Xoffset = trn->dx - trn->oarea.left;
	out->Yoffset = trn->dy - trn->oarea.top;

	return( 0 );
}
Пример #10
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 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
 * 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 
im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
{
	IMAGE *t;
	LutInfo *st;

	/* Check input output. Old-style IO from lut, for simplicity.
	 */
	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_piocheck( in, out ) || 
		im_incheck( lut ) )
		return( -1 );

	/* Cast in to u8/u16/u32.
	 */
	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, t, lut, NULL ) )
                return( -1 );

	/* Force output to be the same type as lut.
	 */
	out->BandFmt = lut->BandFmt;

	/* Output has same number of bands as LUT, unless LUT has 1 band, in
	 * which case output has same number of bands as input.
	 */
	if( lut->Bands != 1 )
		out->Bands = lut->Bands;

	/* Make tables.
	 */
	if( !(st = build_luts( out, lut )) )
		return( -1 );

	/* Set demand hints.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, t, NULL ) )
		return( -1 );

	/* Process!
	 */
        if( im_generate( out, maplut_start, maplut_gen, maplut_stop, t, st ) )
                return( -1 );

        return( 0 );
}
Пример #11
0
int 
im__arith_binary_const( const char *domain,
	IMAGE *in, IMAGE *out, 
	int n, double *c, VipsBandFmt vfmt,
	int format_table[10], 
	im_wrapone_fn fn1, im_wrapone_fn fnn )
{
	PEL *vector;

	if( im_piocheck( in, out ) ||
		im_check_vector( domain, n, in ) ||
		im_check_uncoded( domain, in ) )
		return( -1 );
	if( im_cp_desc( out, in ) )
		return( -1 );
	out->BandFmt = format_table[in->BandFmt];

	/* Some operations need the vector in the input type (eg.
	 * im_equal_vec() where the output type is always uchar and is useless
	 * for comparisons), some need it in the output type (eg.
	 * im_andimage_vec() where we want to get the double to an int so we
	 * can do bitwise-and without having to cast for each pixel), some
	 * need a fixed type (eg. im_powtra_vec(), where we want to keep it as
	 * double).
	 *
	 * Therefore pass in the desired vector type as a param.
	 */
	if( !(vector = make_pixel( out, vfmt, n, c )) )
		return( -1 );

	/* Band-up the input image if we have a >1 vector and
	 * a 1-band image.
	 */
	if( n > 1 && out->Bands == 1 ) {
		IMAGE *t;

		if( !(t = im_open_local( out, domain, "p" )) ||
			im__bandup( domain, in, t, n ) )
			return( -1 );

		in = t;
	}

	if( n == 1 ) {
		if( im_wrapone( in, out, fn1, vector, in ) )
			return( -1 );
	}
	else {
		if( im_wrapone( in, out, fnn, vector, in ) )
			return( -1 );
	}

	return( 0 );
}
Пример #12
0
/**
 * im_benchmark2:
 * @in: input image
 * @out: average image value
 *
 * This operation runs a single im_benchmarkn() and calculates the average
 * pixel value. It's useful if you just want to test image input.
 *
 * See also: im_benchmarkn().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_benchmark2( IMAGE *in, double *out )
{
        IMAGE *t;

        return(
		!(t = im_open_local( in, "benchmarkn", "p" )) ||
                im_benchmarkn( in, t, 1 ) ||
                im_avg( t, out ) 
	);
}
Пример #13
0
/**
 * 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 )
{
	IMAGE *t;

	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 );

	return( 0 );
}
Пример #14
0
/**
 * im_hist:
 * @in: input image
 * @out: output image
 * @bandno: band to plot
 *
 * Find and plot the histogram of @in. If @bandno is -1, plot all bands. 
 * Otherwise plot the specified band.
 *
 * See also: im_histgr(), im_histplot().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_hist( IMAGE *in, IMAGE *out, int bandno )
{
	IMAGE *hist;

	if( !(hist = im_open_local( out, "im_hist", "p" )) ||
		im_histgr( in, hist, bandno ) ||
		im_histplot( hist, out ) )
		return( -1 );

	return( 0 );
}
Пример #15
0
/**
 * im_cmulnorm
 * @in1: input #IMAGE 1
 * @in2: input #IMAGE 2
 * @out: output #IMAGE
 *
 * im_cmulnorm() multiplies two complex images. The complex output is
 * normalised to 1 by dividing both the real and the imaginary part of each
 * pel with the norm. This is useful for phase correlation.  
 *
 * This operation used to be important, but now simply calls im_multiply() 
 * then im_sign().
 *
 * See also: im_multiply(), im_sign().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_cmulnorm( IMAGE *in1, IMAGE *in2, IMAGE *out )
{
	IMAGE *t1;

	if( !(t1 = im_open_local( out, "im_cmulnorm:1", "p" )) ||
		im_multiply( in1, in2, t1 ) || 
		im_sign( t1, out ) )
		return( -1 );
	
	return( 0 );
}
Пример #16
0
int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){
#define FUNCTION_NAME "im_gradcor_raw"

  if( im_piocheck( large, out ) || im_pincheck( small ) )
    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;
  }
  if( im_cp_desc( out, large ) )
    return -1;

  out-> Xsize= 1 + large-> Xsize - small-> Xsize;
  out-> Ysize= 1 + large-> Ysize - small-> Ysize;
  out-> BandFmt= IM_BANDFMT_FLOAT;

  if( im_demand_hint( out, IM_FATSTRIP, large, NULL ) )
    return -1;

  {
    IMAGE *xgrad= im_open_local( out, FUNCTION_NAME ": xgrad", "t" );
    IMAGE *ygrad= im_open_local( out, FUNCTION_NAME ": ygrad", "t" );
    IMAGE **grads= im_allocate_input_array( out, xgrad, ygrad, NULL );

    return ! xgrad || ! ygrad || ! grads
      || im_grad_x( small, xgrad )
      || im_grad_y( small, ygrad )
      || im_generate( out, gradcor_start, gradcor_gen, gradcor_stop, (void*) large, (void*) grads );
  }
#undef FUNCTION_NAME
}
Пример #17
0
/* Just for compatibility. New code should use vips_object_local_array().
 */
int
im_open_local_array( VipsImage *parent, 
	VipsImage **images, int n,
	const char *filename, const char *mode )
{
	int i;

	for( i = 0; i < n; i++ )
		if( !(images[i] = im_open_local( parent, filename, mode )) )
			return( -1 );

	return( 0 );
}
Пример #18
0
int
im_flood_blob_copy( IMAGE *in, IMAGE *out, int x, int y, PEL *ink )
{
	IMAGE *t;

	if( !(t = im_open_local( out, "im_flood_blob_copy", "t" )) ||
		im_copy( in, t ) ||
		im_flood_blob( t, x, y, ink, NULL ) ||
		im_copy( t, out ) ) 
		return( -1 );

	return( 0 );
}
Пример #19
0
int
im_flood_other_copy( IMAGE *test, IMAGE *mark, IMAGE *out, 
	int x, int y, int serial )
{
	IMAGE *t;

	if( !(t = im_open_local( out, "im_flood_other_copy", "t" )) ||
		im_copy( mark, t ) ||
		im_flood_other( test, t, x, y, serial, NULL ) ||
		im_copy( t, out ) ) 
		return( -1 );

	return( 0 );
}
Пример #20
0
/**
 * im_histplot:
 * @in: input image
 * @out: output image
 *
 * Plot a 1 by any or any by 1 image file as a max by any or 
 * any by max image using these rules:
 * 
 * <emphasis>unsigned char</emphasis> max is always 256 
 *
 * <emphasis>other unsigned integer types</emphasis> output 0 - maxium 
 * value of @in.
 *
 * <emphasis>signed int types</emphasis> min moved to 0, max moved to max + min.
 *
 * <emphasis>float types</emphasis> min moved to 0, max moved to any 
 * (square output)
 *
 * See also: im_hist_indexed(), im_histeq().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_histplot( IMAGE *in, IMAGE *out )
{
	IMAGE *t1;

	if( im_check_hist( "im_histplot", in ) )
		return( -1 );

	if( !(t1 = im_open_local( out, "im_histplot:1", "p" )) ||
		normalise( in, t1 ) ||
		plot( t1, out ) )
		return( -1 );
	
	return( 0 );
}
Пример #21
0
/**
 * im_zerox:
 * @in: input image
 * @out: output image
 * @sign: detect positive or negative zero crossings
 *
 * im_zerox() detects the positive or negative zero crossings @in, 
 * depending on @sign. If @sign is -1, negative zero crossings are returned,
 * if @sign is 1, positive zero crossings are returned.
 *
 * The output image is byte with zero crossing set to 255 and all other values
 * set to zero. Input can have any number of channels, and be any non-complex 
 * type.
 *
 * See also: im_conv(), im_rot90.
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_zerox( IMAGE *in, IMAGE *out, int sign )
{
	IMAGE *t1;

	if( sign != -1 && sign != 1 ) {
		im_error( "im_zerox", "%s", _( "flag not -1 or 1" ) );
		return( -1 );
	}
	if( in->Xsize < 2 ) {
		im_error( "im_zerox", "%s", _( "image too narrow" ) );
		return( -1 );
	}
	if( !(t1 = im_open_local( out, "im_zerox" , "p" )) ||
		im_piocheck( in, t1 ) ||
		im_check_uncoded( "im_zerox", in ) ||
		im_check_noncomplex( "im_zerox", in ) )
		return( -1 );
	if( vips_bandfmt_isuint( in->BandFmt ) )
		/* Unsigned type, therefore there will be no zero-crossings.
		 */
		return( im_black( out, in->Xsize, in->Ysize, in->Bands ) );

	/* Force output to be BYTE. Output is narrower than input by 1 pixel.
	 */
	if( im_cp_desc( t1, in ) )
		return( -1 );
	t1->BandFmt = IM_BANDFMT_UCHAR;
	t1->Xsize -= 1;

	/* Set hints - THINSTRIP is ok with us.
	 */
	if( im_demand_hint( t1, IM_THINSTRIP, NULL ) )
		return( -1 );

	/* Generate image.
	 */
	if( im_generate( t1, im_start_one, zerox_gen, im_stop_one, 
		in, GINT_TO_POINTER( sign ) ) )
		return( -1 );

	/* Now embed it in a larger image.
	 */
	if( im_embed( t1, out, 0, 0, 0, in->Xsize, in->Ysize ) )
		return( -1 );

	return( 0 );
}
Пример #22
0
/**
 * im_stdif:
 * @in: input image
 * @out: output image
 * @a: weight of new mean
 * @m0: target mean
 * @b: weight of new deviation
 * @s0:target deviation
 * @xwin: width of region
 * @ywin: height of region
 *
 * im_stdif() preforms statistical differencing according to the formula
 * given in page 45 of the book "An Introduction to Digital Image
 * Processing" by Wayne Niblack. This transformation emphasises the way in
 * which a pel differs statistically from its neighbours. It is useful for
 * enhancing low-contrast images with lots of detail, such as X-ray plates.
 *
 * At point (i,j) the output is given by the equation:
 *
 * vout(i,j) = @a * @m0 + (1 - @a) * meanv +
 *       (vin(i,j) - meanv) * (@b * @s0) / (@s0 + @b * stdv)
 *
 * Values @a, @m0, @b and @s0 are entered, while meanv and stdv are the values
 * calculated over a moving window of size @xwin, @ywin centred on pixel (i,j).
 * @m0 is the new mean, @a is the weight given to it. @s0 is the new standard
 * deviation, @b is the weight given to it.
 *
 * Try:
 *
 * vips im_stdif $VIPSHOME/pics/huysum.v fred.v 0.5 128 0.5 50 11 11
 *
 * The operation works on one-band uchar images only, and writes a one-band
 * uchar image as its result. The output image has the same size as the
 * input.
 *
 * See also: im_lhisteq().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_stdif( IMAGE *in, IMAGE *out,
          double a, double m0, double b, double s0,
          int xwin, int ywin )
{
    IMAGE *t1;

    if( !(t1 = im_open_local( out, "im_stdif:1", "p" )) ||
            im_embed( in, t1, 1, xwin / 2, ywin / 2,
                      in->Xsize + xwin - 1,
                      in->Ysize + ywin - 1 ) ||
            im_stdif_raw( t1, out, a, m0, b, s0, xwin, ywin ) )
        return( -1 );

    return( 0 );
}
Пример #23
0
/**
 * im_tone_build:
 * @out: output image
 * @Lb: black-point [0-100]
 * @Lw: white-point [0-100]
 * @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_range(), but set 32767 and 32767 as values for @in_max
 * and @out_max. This makes a curve suitable for correcting LABS
 * images, the most common case.
 *
 * See also: im_tone_build_range().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_tone_build( IMAGE *out,
               double Lb, double Lw,
               double Ps, double Pm, double Ph,
               double S, double M, double H )
{
    IMAGE *t1;

    if( !(t1 = im_open_local( out, "im_tone_build", "p" )) ||
            im_tone_build_range( t1, 32767, 32767,
                                 Lb, Lw, Ps, Pm, Ph, S, M, H ) ||
            im_clip2fmt( t1, out, IM_BANDFMT_SHORT ) )
        return( -1 );

    return( 0 );
}
Пример #24
0
/* The above, with a border to make out the same size as in.
 */
int 
im_dilate( IMAGE *in, IMAGE *out, INTMASK *m )
{
	IMAGE *t1 = im_open_local( out, "im_dilate:1", "p" );

	if( !t1 || 
		im_embed( in, t1, 1, m->xsize / 2, m->ysize / 2, 
			in->Xsize + m->xsize - 1, 
			in->Ysize + m->ysize - 1 ) ||
		im_dilate_raw( t1, out, m ) )
		return( -1 );

	out->Xoffset = 0;
	out->Yoffset = 0;

	return( 0 );
}
Пример #25
0
/**
 * im_lhisteq:
 * @in: input image
 * @out: output image
 * @xwin: width of region
 * @ywin: 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_stdif(), im_heq().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_lhisteq( IMAGE *in, IMAGE *out, int xwin, int ywin )
{
	IMAGE *t1;

	if( !(t1 = im_open_local( out, "im_lhisteq:1", "p" )) ||
		im_embed( in, t1, 1, 
			xwin / 2, ywin / 2, 
			in->Xsize + xwin - 1, in->Ysize + ywin - 1 ) ||
		im_lhisteq_raw( t1, out, xwin, ywin ) )
		return( -1 );

	out->Xoffset = 0;
	out->Yoffset = 0;

	return( 0 );
}
Пример #26
0
/**
 * im_erode:
 * @in: input image
 * @out: output image
 * @mask: mask
 *
 * im_erode() performs a morphological erode operation on @in using @mask as a
 * structuring element. The whole mask must match for the output pixel to be
 * set, that is, the result is the logical AND of the selected input pixels.
 *
 * The image should have 0 (black) for no object and 255
 * (non-zero) for an object. Note that this is the reverse of the usual
 * convention for these operations, but more convenient when combined with the
 * boolean operators im_andimage() and friends. The output image is the same
 * size as the input image: edge pxels are made by expanding the input image
 * as necessary in the manner of im_conv().
 *
 * Mask coefficients can be either 0 (for object) or 255 (for background) 
 * or 128 (for do not care).  The origin of the mask is at location
 * (m.xsize / 2, m.ysize / 2), integer division.  All algorithms have been 
 * based on the book "Fundamentals of Digital Image Processing" by A. Jain, 
 * pp 384-388, Prentice-Hall, 1989. 
 *
 * See the boolean operations im_andimage(), im_orimage() and im_eorimage() 
 * for analogues of the usual set difference and set union operations.
 *
 * Operations are performed using the processor's vector unit,
 * if possible. Disable this with --vips-novector or IM_NOVECTOR.
 *
 * See also: im_dilate().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_erode( IMAGE *in, IMAGE *out, INTMASK *mask )
{
	IMAGE *t1 = im_open_local( out, "im_erode:1", "p" );

	if( !t1 || 
		im_embed( in, t1, 1, mask->xsize / 2, mask->ysize / 2, 
			in->Xsize + mask->xsize - 1, 
			in->Ysize + mask->ysize - 1 ) ||
		morphology( t1, out, mask, ERODE ) )
		return( -1 );

	out->Xoffset = 0;
	out->Yoffset = 0;

	return( 0 );
}
Пример #27
0
/**
 * im_tbjoin:
 * @top: image to go on top
 * @bottom: image to go on bottom
 * @out: output image
 *
 * Join @top and @bottom together, up-down. If one is wider than the
 * other, @out will be has wide as the smaller.
 *
 * If the number of bands differs, one of the images 
 * must have one band. In this case, an n-band image is formed from the 
 * one-band image by joining n copies of the one-band image together, and then
 * the two n-band images are operated upon.
 *
 * The two input images are cast up to the smallest common type (see table 
 * Smallest common format in 
 * <link linkend="VIPS-arithmetic">arithmetic</link>).
 *
 * See also: im_insert(), im_tbjoin().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_tbjoin( IMAGE *top, IMAGE *bottom, IMAGE *out )
{
	IMAGE *t1;

	/* Paste top and bottom together, cut off any leftovers.
	 */
	if( !(t1 = im_open_local( out, "im_tbjoin:1", "p" )) ||
		im_insert( top, bottom, t1, 0, top->Ysize ) ||
		im_extract_area( t1, out, 
			0, 0, IM_MIN( top->Xsize, bottom->Xsize ), t1->Ysize ) )
		return( -1 );

	out->Xoffset = 0;
	out->Yoffset = top->Ysize;

	return( 0 );
}
Пример #28
0
/**
 * 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)
{
  IMAGE *t1 = im_open_local (out, "im_contrast_surface intermediate", "p");

  if (!t1
      || im_embed (in, t1, 1, half_win_size, half_win_size,
		   in->Xsize + DOUBLE (half_win_size),
		   in->Ysize + DOUBLE (half_win_size))
      || im_contrast_surface_raw (t1, out, half_win_size, spacing))

    return -1;

  out->Xoffset = 0;
  out->Yoffset = 0;

  return 0;
}
Пример #29
0
/* The above, with a border to make out the same size as in.
 */
int
im_fastcor( IMAGE *in, IMAGE *ref, IMAGE *out )
{
    IMAGE *t1 = im_open_local( out, "im_fastcor intermediate", "p" );

    if( !t1 ||
            im_embed( in, t1, 1,
                      ref->Xsize / 2, ref->Ysize / 2,
                      in->Xsize + ref->Xsize - 1,
                      in->Ysize + ref->Ysize - 1 ) ||
            im_fastcor_raw( t1, ref, out ) )
        return( -1 );

    out->Xoffset = 0;
    out->Yoffset = 0;

    return( 0 );
}
Пример #30
0
/* similarity+tbmerge.
 */
int
im__tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
	double a, double b, double dx, double dy, int mwidth )
{
	VipsTransformation trn;
	IMAGE *t1 = im_open_local( out, "im_lrmosaic1:2", "p" );
	VipsBuf buf;
	char text[1024];

	/* Scale, rotate and displace sec.
	 */
	if( !t1 || apply_similarity( &trn, sec, t1, a, b, dx, dy ) )
		return( -1 );

	/* And join to ref.
	 */
	if( im__tbmerge( ref, t1, out, 
		-trn.oarea.left, -trn.oarea.top, mwidth ) )
		return( -1 );

	/* Note parameters in history file ... for global balance to pick up
	 * later.
	 */
	im__add_mosaic_name( out );
	vips_buf_init_static( &buf, text, 1024 );
	vips_buf_appendf( &buf, "#TBROTSCALE <%s> <%s> <%s> <",
		im__get_mosaic_name( ref ), 
		im__get_mosaic_name( sec ), 
		im__get_mosaic_name( out ) );  
	vips_buf_appendg( &buf, a );
	vips_buf_appendf( &buf, "> <" );
	vips_buf_appendg( &buf, b );
	vips_buf_appendf( &buf, "> <" );
	vips_buf_appendg( &buf, dx );
	vips_buf_appendf( &buf, "> <" );
	vips_buf_appendg( &buf, dy );
	vips_buf_appendf( &buf, "> <%d>", mwidth );
	if( im_histlin( out, "%s", vips_buf_all( &buf ) ) )
		return( -1 );

	return( 0 );
}