polish, add test for find_trim
This commit is contained in:
parent
effc1d53d0
commit
6359c92c01
@ -51,46 +51,29 @@ typedef struct _VipsFindTrim {
|
|||||||
|
|
||||||
VipsImage *in;
|
VipsImage *in;
|
||||||
double threshold;
|
double threshold;
|
||||||
|
VipsArrayDouble *background;
|
||||||
|
|
||||||
int left;
|
int left;
|
||||||
int top;
|
int top;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
double *ones;
|
|
||||||
double *background;
|
|
||||||
int n;
|
|
||||||
} VipsFindTrim;
|
} VipsFindTrim;
|
||||||
|
|
||||||
typedef VipsOperationClass VipsFindTrimClass;
|
typedef VipsOperationClass VipsFindTrimClass;
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsFindTrim, vips_find_trim, VIPS_TYPE_OPERATION );
|
G_DEFINE_TYPE( VipsFindTrim, vips_find_trim, VIPS_TYPE_OPERATION );
|
||||||
|
|
||||||
static void
|
|
||||||
vips_find_trim_finalize( GObject *gobject )
|
|
||||||
{
|
|
||||||
VipsFindTrim *find_trim = (VipsFindTrim *) gobject;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "vips_find_trim_finalize: " );
|
|
||||||
vips_object_print_name( VIPS_OBJECT( gobject ) );
|
|
||||||
printf( "\n" );
|
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
VIPS_FREE( find_trim->background );
|
|
||||||
VIPS_FREE( find_trim->ones );
|
|
||||||
|
|
||||||
G_OBJECT_CLASS( vips_find_trim_parent_class )->finalize( gobject );
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vips_find_trim_build( VipsObject *object )
|
vips_find_trim_build( VipsObject *object )
|
||||||
{
|
{
|
||||||
VipsFindTrim *find_trim = (VipsFindTrim *) object;
|
VipsFindTrim *find_trim = (VipsFindTrim *) object;
|
||||||
VipsImage **t = (VipsImage **) vips_object_local_array( object, 20 );
|
VipsImage **t = (VipsImage **) vips_object_local_array( object, 20 );
|
||||||
|
|
||||||
int i;
|
double *background;
|
||||||
|
int n;
|
||||||
|
double *neg_bg;
|
||||||
double *ones;
|
double *ones;
|
||||||
|
int i;
|
||||||
double left;
|
double left;
|
||||||
double top;
|
double top;
|
||||||
double right;
|
double right;
|
||||||
@ -102,27 +85,21 @@ vips_find_trim_build( VipsObject *object )
|
|||||||
if( vips_image_decode( find_trim->in, &t[0] ) )
|
if( vips_image_decode( find_trim->in, &t[0] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Fetch pixel (0, 0) as the background value.
|
|
||||||
*/
|
|
||||||
if( vips_getpoint( t[0],
|
|
||||||
&find_trim->background, &find_trim->n,
|
|
||||||
0, 0, NULL ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* We want to subtract the bg.
|
/* We want to subtract the bg.
|
||||||
*/
|
*/
|
||||||
if( !(ones = VIPS_ARRAY( find_trim, find_trim->n, double )) )
|
background = vips_array_double_get( find_trim->background, &n );
|
||||||
|
if( !(neg_bg = VIPS_ARRAY( find_trim, n, double )) ||
|
||||||
|
!(ones = VIPS_ARRAY( find_trim, n, double )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
for( i = 0; i < find_trim->n; i++ ) {
|
for( i = 0; i < n; i++ ) {
|
||||||
|
neg_bg[i] = -1 * background[i];
|
||||||
ones[i] = 1.0;
|
ones[i] = 1.0;
|
||||||
find_trim->background[i] *= -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth, find difference from bg, abs, threshold.
|
/* Smooth, find difference from bg, abs, threshold.
|
||||||
*/
|
*/
|
||||||
if( vips_median( t[0], &t[1], 3, NULL ) ||
|
if( vips_median( t[0], &t[1], 3, NULL ) ||
|
||||||
vips_linear( t[1], &t[2],
|
vips_linear( t[1], &t[2], ones, neg_bg, n, NULL ) ||
|
||||||
ones, find_trim->background, find_trim->n, NULL ) ||
|
|
||||||
vips_abs( t[2], &t[3], NULL ) ||
|
vips_abs( t[2], &t[3], NULL ) ||
|
||||||
vips_more_const1( t[3], &t[4], find_trim->threshold, NULL ) )
|
vips_more_const1( t[3], &t[4], find_trim->threshold, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -167,9 +144,7 @@ vips_find_trim_class_init( VipsFindTrimClass *class )
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class = (GObjectClass *) class;
|
GObjectClass *gobject_class = (GObjectClass *) class;
|
||||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
|
||||||
|
|
||||||
gobject_class->finalize = vips_find_trim_finalize;
|
|
||||||
gobject_class->set_property = vips_object_set_property;
|
gobject_class->set_property = vips_object_set_property;
|
||||||
gobject_class->get_property = vips_object_get_property;
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
@ -192,6 +167,13 @@ vips_find_trim_class_init( VipsFindTrimClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsFindTrim, threshold ),
|
G_STRUCT_OFFSET( VipsFindTrim, threshold ),
|
||||||
0, INFINITY, 10.0 );
|
0, INFINITY, 10.0 );
|
||||||
|
|
||||||
|
VIPS_ARG_BOXED( class, "background", 3,
|
||||||
|
_( "Background" ),
|
||||||
|
_( "Color for background pixels" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsFindTrim, background ),
|
||||||
|
VIPS_TYPE_ARRAY_DOUBLE );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "left", 5,
|
VIPS_ARG_INT( class, "left", 5,
|
||||||
_( "Left" ),
|
_( "Left" ),
|
||||||
_( "Left edge of image" ),
|
_( "Left edge of image" ),
|
||||||
@ -226,6 +208,7 @@ static void
|
|||||||
vips_find_trim_init( VipsFindTrim *find_trim )
|
vips_find_trim_init( VipsFindTrim *find_trim )
|
||||||
{
|
{
|
||||||
find_trim->threshold = 10;
|
find_trim->threshold = 10;
|
||||||
|
find_trim->background = vips_array_double_newv( 1, 255.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -239,9 +222,20 @@ vips_find_trim_init( VipsFindTrim *find_trim )
|
|||||||
*
|
*
|
||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @threshold: background / object threshold
|
* * @threshold: %gdouble, background / object threshold
|
||||||
|
* * @background: #VipsArrayDouble, background colour, default 255
|
||||||
*
|
*
|
||||||
* See also: vips_extract_area(), vips_smartcrop().
|
* Search @in for the bounding box of the non-background area.
|
||||||
|
*
|
||||||
|
* @in is median-filtered, then all the row and column sums of the absolute
|
||||||
|
* difference from @background are calculated in a
|
||||||
|
* single pass through the image, then the first row or column in each of the
|
||||||
|
* four directions is found where the sum is greater than @threshold.
|
||||||
|
*
|
||||||
|
* @background defaults to 255. Set another value, or use vips_getpoint() to
|
||||||
|
* pick a value from an edge. @threshold defaults to 10.
|
||||||
|
*
|
||||||
|
* See also: vips_getpoint(), vips_extract_area(), vips_smartcrop().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error
|
* Returns: 0 on success, -1 on error
|
||||||
*/
|
*/
|
||||||
|
@ -607,6 +607,7 @@ vips_embed_class_init( VipsEmbedClass *class )
|
|||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsEmbed, background ),
|
G_STRUCT_OFFSET( VipsEmbed, background ),
|
||||||
VIPS_TYPE_ARRAY_DOUBLE );
|
VIPS_TYPE_ARRAY_DOUBLE );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -641,6 +641,21 @@ class TestArithmetic(unittest.TestCase):
|
|||||||
self.assertAlmostEqual(p1, 0)
|
self.assertAlmostEqual(p1, 0)
|
||||||
self.assertAlmostEqual(p2, 10)
|
self.assertAlmostEqual(p2, 10)
|
||||||
|
|
||||||
|
def test_find_trim(self):
|
||||||
|
im = Vips.Image.black(50, 60) + 100
|
||||||
|
test = im.embed(10, 20, 200, 300, extend = "white")
|
||||||
|
|
||||||
|
test.write_to_file("x.v")
|
||||||
|
|
||||||
|
for x in unsigned_formats + float_formats:
|
||||||
|
a = test.cast(x)
|
||||||
|
left, top, width, height = a.find_trim()
|
||||||
|
|
||||||
|
self.assertEqual(left, 10)
|
||||||
|
self.assertEqual(top, 20)
|
||||||
|
self.assertEqual(width, 50)
|
||||||
|
self.assertEqual(height, 60)
|
||||||
|
|
||||||
def test_profile(self):
|
def test_profile(self):
|
||||||
test = Vips.Image.black(100, 100).draw_rect(100, 40, 50, 1, 1)
|
test = Vips.Image.black(100, 100).draw_rect(100, 40, 50, 1, 1)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user