Exemplo n.º 1
0
static int
vips_compass_build( VipsObject *object )
{
	VipsConvolution *convolution = (VipsConvolution *) object;
	VipsCompass *compass = (VipsCompass *) object;
	VipsImage **masks;
	VipsImage *mask;
	VipsImage **images;
	int i; 
	VipsImage **abs;
	VipsImage **combine;
	VipsImage *x;

	g_object_set( compass, "out", vips_image_new(), NULL ); 

	if( VIPS_OBJECT_CLASS( vips_compass_parent_class )->build( object ) )
		return( -1 );

	masks = (VipsImage **) 
		vips_object_local_array( object, compass->times );
	images = (VipsImage **) 
		vips_object_local_array( object, compass->times );
	abs = (VipsImage **) 
		vips_object_local_array( object, compass->times );
	combine = (VipsImage **) 
		vips_object_local_array( object, compass->times );

	mask = convolution->M;
	for( i = 0; i < compass->times; i++ ) {
		if( vips_conv( convolution->in, &images[i], mask, 
			"precision", compass->precision,
			"layers", compass->layers,
			"cluster", compass->cluster,
			NULL ) )
			return( -1 ); 
		if( vips_rot45( mask, &masks[i],
			"angle", compass->angle,
			NULL ) )
			return( -1 ); 

		mask = masks[i];
	}

	for( i = 0; i < compass->times; i++ )
		if( vips_abs( images[i], &abs[i], NULL ) )
			return( -1 ); 

	switch( compass->combine ) { 
	case VIPS_COMBINE_MAX:
		if( vips_bandrank( abs, &combine[0], compass->times,
			"index", compass->times - 1,
			NULL ) )
			return( -1 ); 
		x = combine[0];
		break;

	case VIPS_COMBINE_SUM:
		x = abs[0];
		for( i = 1; i < compass->times; i++ ) {
			if( vips_add( x, abs[i], &combine[i], NULL ) )
				return( -1 );
			x = combine[i];
		}
		break;

	default:
		/* Silence compiler wrning.
		 */
		x = NULL;
		g_assert( 0 );
	}

	if( vips_image_write( x, convolution->out ) )
		return( -1 ); 

	return( 0 );
}
Exemplo n.º 2
0
static int
vips_smartcrop_attention( VipsSmartcrop *smartcrop, 
	VipsImage *in, int *left, int *top )
{
	/* From smartcrop.js.
	 */
	static double skin_vector[] = {-0.78, -0.57, -0.44};
	static double ones[] = {1.0, 1.0, 1.0};

	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( smartcrop ), 24 );

	double hscale;
	double vscale;
	double sigma;
	double max;
	int x_pos;
	int y_pos;

	/* The size we shrink to gives the precision with which we can place
	 * the crop
	 */
	hscale = 32.0 / in->Xsize;
	vscale = 32.0 / in->Ysize;
	sigma = VIPS_MAX( sqrt( pow( smartcrop->width * hscale, 2 ) +
		pow( smartcrop->height * vscale, 2 ) ) / 10, 1.0 );
	if ( vips_resize( in, &t[17], hscale,
		"vscale", vscale,
		NULL ) )
		return( -1 );

	/* Simple edge detect.
	 */
	if( !(t[21] = vips_image_new_matrixv( 3, 3,
		 0.0, -1.0,  0.0, 
		-1.0,  4.0, -1.0, 
		 0.0, -1.0,  0.0 )) )
		return( -1 );

	/* Convert to XYZ and just use the first three bands.
	 */
	if( vips_colourspace( t[17], &t[0], VIPS_INTERPRETATION_XYZ, NULL ) ||
		vips_extract_band( t[0], &t[1], 0, "n", 3, NULL ) )
		return( -1 );

	/* Edge detect on Y. 
	 */
	if( vips_extract_band( t[1], &t[2], 1, NULL ) ||
		vips_conv( t[2], &t[3], t[21], 
			"precision", VIPS_PRECISION_INTEGER,
			NULL ) ||
		vips_linear1( t[3], &t[4], 5.0, 0.0, NULL ) ||
		vips_abs( t[4], &t[14], NULL ) )
		return( -1 );

	/* Look for skin colours. Taken from smartcrop.js.
	 */
	if( 
		/* Normalise to magnitude of colour in XYZ.
		 */
		pythagoras( smartcrop, t[1], &t[5] ) ||
		vips_divide( t[1], t[5], &t[6], NULL ) ||

		/* Distance from skin point.
		 */
		vips_linear( t[6], &t[7], ones, skin_vector, 3, NULL ) ||
		pythagoras( smartcrop, t[7], &t[8] ) ||

		/* Rescale to 100 - 0 score.
		 */
		vips_linear1( t[8], &t[9], -100.0, 100.0, NULL ) ||

		/* Ignore dark areas.
		 */
		vips_more_const1( t[2], &t[10], 5.0, NULL ) ||
		!(t[11] = vips_image_new_from_image1( t[10], 0.0 )) ||
		vips_ifthenelse( t[10], t[9], t[11], &t[15], NULL ) )
		return( -1 );

	/* Look for saturated areas.
	 */
	if( vips_colourspace( t[1], &t[12], 
		VIPS_INTERPRETATION_LAB, NULL ) ||
		vips_extract_band( t[12], &t[13], 1, NULL ) ||
		vips_ifthenelse( t[10], t[13], t[11], &t[16], NULL ) )
		return( -1 );

	/* Sum, blur and find maxpos.
	 *
	 * The amount of blur is related to the size of the crop
	 * area: how large an area we want to consider for the scoring
	 * function.
	 */

	if( vips_sum( &t[14], &t[18], 3, NULL ) ||
		vips_gaussblur( t[18], &t[19], sigma, NULL ) ||
		vips_max( t[19], &max, "x", &x_pos, "y", &y_pos, NULL ) )
		return( -1 ); 

	/* Centre the crop over the max.
	 */
	*left = VIPS_CLIP( 0, 
		x_pos / hscale - smartcrop->width / 2, 
		in->Xsize - smartcrop->width );
	*top = VIPS_CLIP( 0, 
		y_pos / vscale - smartcrop->height / 2, 
		in->Ysize - smartcrop->height ); 

	return( 0 ); 
}