test for bandrank and bandmean

This commit is contained in:
John Cupitt 2014-09-25 09:58:51 +01:00
parent b402bb173f
commit 7915308155
2 changed files with 57 additions and 22 deletions

View File

@ -62,7 +62,7 @@ typedef struct _VipsBandrank {
/* The input images.
*/
VipsArea *in;
VipsArrayImage *in;
int index; /* Pick out this one */
} VipsBandrank;
@ -178,27 +178,34 @@ vips_bandrank_build( VipsObject *object )
VipsBandrank *bandrank = (VipsBandrank *) object;
if( bandrank->in ) {
int n;
VipsImage **in = vips_array_image_get( bandrank->in, &n );
VipsImage **band = (VipsImage **)
vips_object_local_array( object, bandrank->in->n );
vips_object_local_array( object, n );
if( bandrank->in->n == 1 )
int i;
for( i = 0; i < n; i++ )
if( vips_check_noncomplex( class->nickname, in[i] ) )
return( -1 );
if( n == 1 )
return( vips_bandary_copy( bandary ) );
/* We need to keep one band element for every input image
* on the stack.
*/
if( sizeof( double ) * bandrank->in->n > SORT_BUFFER ) {
if( sizeof( double ) * n > SORT_BUFFER ) {
vips_error( class->nickname,
"%s", _( "too many input images" ) );
return( -1 );
}
if( vips__bandalike_vec( class->nickname,
bandrank->in->data, band, bandrank->in->n, 0 ) )
if( vips__bandalike_vec( class->nickname, in, band, n, 0 ) )
return( -1 );
bandary->in = band;
bandary->n = bandrank->in->n;
bandary->n = n;
bandary->out_bands = band[0]->Bands;
if( bandrank->index == -1 )
@ -281,7 +288,7 @@ vips_bandrankv( VipsImage **in, VipsImage **out, int n, va_list ap )
* image in which each band element is selected from the sorted list by the
* @index parameter. For example, if @index
* is zero, then each output band element will be the minimum of all the
* corresponding input band element.
* corresponding input band elements.
*
* By default, @index is -1, meaning pick the median value.
*

View File

@ -44,7 +44,7 @@ class TestConversion(unittest.TestCase):
# run a function on an image and on a single pixel, the results
# should match
def run_cmp(self, message, im, x, y, fn):
def run_cmp_unary(self, message, im, x, y, fn):
a = im.getpoint(x, y)
v1 = fn(a)
im2 = fn(im)
@ -53,7 +53,7 @@ class TestConversion(unittest.TestCase):
# run a function on a pair of images and on a pair of pixels, the results
# should match
def run_cmp2(self, message, left, right, x, y, fn):
def run_cmp_binary(self, message, left, right, x, y, fn):
a = left.getpoint(x, y)
b = right.getpoint(x, y)
v1 = fn(a, b)
@ -63,20 +63,25 @@ class TestConversion(unittest.TestCase):
# run a function on a pair of images
# 50,50 and 10,10 should have different values on the test image
def run_test2(self, message, left, right, fn):
self.run_cmp2(message, left, right, 50, 50, fn)
self.run_cmp2(message, left, right, 10, 10, fn)
def run_testbinary(self, message, left, right, fn):
self.run_cmp_binary(message, left, right, 50, 50, fn)
self.run_cmp_binary(message, left, right, 10, 10, fn)
# run a function on an image,
# 50,50 and 10,10 should have different values on the test image
def run_testunary(self, message, im, fn):
self.run_cmp(message, im, 50, 50, fn)
self.run_cmp(message, im, 10, 10, fn)
self.run_cmp_unary(message, im, 50, 50, fn)
self.run_cmp_unary(message, im, 10, 10, fn)
def run_unary(self, images, fn, fmt = all_formats):
[self.run_testunary(fn.func_name + ' image', x.cast(y), fn)
[self.run_testunary(fn.func_name + (' %s' % y), x.cast(y), fn)
for x in images for y in fmt]
def run_binary(self, images, fn, fmt = all_formats):
[self.run_testbinary(fn.func_name + (' %s %s' % (y, z)),
x.cast(y), x.cast(z), fn)
for x in images for y in fmt for z in fmt]
def setUp(self):
im = Vips.Image.mask_ideal(100, 100, 0.5, reject = True, optical = True)
self.colour = im * [1, 2, 3] + [2, 3, 4]
@ -111,13 +116,36 @@ class TestConversion(unittest.TestCase):
self.run_unary([self.colour], band_eor, fmt = int_formats)
def test_bandjoin(self):
im2 = Vips.Image.bandjoin([self.colour, self.mono])
def bandjoin(x, y):
if isinstance(x, Vips.Image) and isinstance(y, Vips.Image):
return x.bandjoin2(y)
else:
return x + y
self.assertEqual(im2.bands, self.colour.bands + self.mono.bands)
v = im2.getpoint(10, 10)
self.assertAlmostEqualObjects(v, [2, 3, 4, 3])
v = im2.getpoint(50, 50)
self.assertAlmostEqualObjects(v, [3, 5, 7, 5])
self.run_binary(self.all_images, bandjoin)
def test_bandmean(self):
def bandmean(x):
if isinstance(x, Vips.Image):
return x.bandmean()
else:
return [sum(x) / len(x)]
self.run_unary([self.colour], bandmean, fmt = noncomplex_formats)
def test_bandrank(self):
def median(x, y):
joined = zip(x, y)
map(lambda x: list(x).sort(), joined)
return map(lambda x: x[len(x) / 2], joined)
def bandrank(x, y):
if isinstance(x, Vips.Image) and isinstance(y, Vips.Image):
return Vips.Image.bandrank([x, y])
else:
return median(x, y)
self.run_binary(self.all_images, bandrank, fmt = noncomplex_formats)
if __name__ == '__main__':
unittest.main()